#include   "tx_api.h"
#include   "nx_api.h"
#include   "nx_tcp.h"
#include   "nx_secure_tls_api.h"
#include   "tls_test_utility.h"

extern void    test_control_return(UINT status);

#if !defined(NX_SECURE_TLS_CLIENT_DISABLED) && !defined(NX_SECURE_TLS_SERVER_DISABLED) && !defined(NX_SECURE_DISABLE_X509)
#define __LINUX__

#define     DEMO_STACK_SIZE  4096 //  (3 * 1024 / sizeof(ULONG))

/* Define the IP thread's stack area.  */
#define IP_STACK_SIZE 4096 //(2 * 1024 / sizeof(ULONG))

/* Define packet pool for the demonstration.  */
#define NX_PACKET_POOL_BYTES  ((1536 + sizeof(NX_PACKET)) * 20)
#define NX_PACKET_POOL_SIZE (NX_PACKET_POOL_BYTES/sizeof(ULONG) + 64 / sizeof(ULONG))

/* Define the ARP cache area.  */
#define ARP_AREA_SIZE 1024 // (512 / sizeof(ULONG))

#define TOTAL_STACK_SPACE (2 * (DEMO_STACK_SIZE + IP_STACK_SIZE + NX_PACKET_POOL_SIZE + ARP_AREA_SIZE))


/* Define the ThreadX and NetX object control blocks...  */

static TX_THREAD               ntest_0;
static TX_THREAD               ntest_1;
static TX_THREAD               sync_thread;


static NX_PACKET_POOL          pool_0;
static NX_PACKET_POOL          pool_1;
static NX_IP                   ip_0;
static NX_IP                   ip_1;
static NX_TCP_SOCKET           client_socket;
static NX_TCP_SOCKET           server_socket;
static NX_SECURE_TLS_SESSION   client_tls_session;
static NX_SECURE_TLS_SESSION   server_tls_session;

static NX_SECURE_X509_CERT certificate;
static NX_SECURE_X509_CERT server_certificate;
static NX_SECURE_X509_CERT ica_certificate;
static NX_SECURE_X509_CERT client_certificate;
static NX_SECURE_X509_CERT remote_certificate, remote_issuer, remote_issuer2;
static NX_SECURE_X509_CERT client_remote_certificate, client_remote_issuer;
static NX_SECURE_X509_CERT trusted_certificate;

static UCHAR remote_cert_buffer[2000];
static UCHAR remote_issuer_buffer[2000];
static UCHAR remote_issuer2_buffer[2000];
static UCHAR client_remote_cert_buffer[2000];
static UCHAR client_remote_issuer_buffer[2000];

static UCHAR server_packet_buffer[4000];
static UCHAR client_packet_buffer[4000];

static CHAR server_crypto_metadata[16000];
static CHAR client_crypto_metadata[16000];

static CHAR sync_thread_stack[1024];
static CHAR server_stack[DEMO_STACK_SIZE];
static CHAR client_stack[DEMO_STACK_SIZE];

/* Test PKI (3-level). */
#include "test_ca_cert.c"
#define ca_cert_der test_ca_cert_der
#define ca_cert_der_len test_ca_cert_der_len

/*  Cryptographic routines. */
extern const NX_SECURE_TLS_CRYPTO nx_crypto_tls_ciphers;

static UCHAR ica_cert_der[] = {
  0x30, 0x82, 0x03, 0xdf, 0x30, 0x82, 0x02, 0xc7, 0xa0, 0x03, 0x02, 0x01,
  0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
  0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x7a, 0x31, 0x0b, 0x30,
  0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b,
  0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31,
  0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x53, 0x61,
  0x6e, 0x20, 0x44, 0x69, 0x65, 0x67, 0x6f, 0x31, 0x16, 0x30, 0x14, 0x06,
  0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0d, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73,
  0x73, 0x20, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x31, 0x14, 0x30, 0x12, 0x06,
  0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x4e, 0x65, 0x74, 0x58, 0x20, 0x53,
  0x65, 0x63, 0x75, 0x72, 0x65, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55,
  0x04, 0x03, 0x0c, 0x13, 0x4e, 0x65, 0x74, 0x58, 0x20, 0x53, 0x65, 0x63,
  0x75, 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41, 0x30,
  0x1e, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x33, 0x33, 0x31, 0x32, 0x31, 0x30,
  0x30, 0x30, 0x32, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x33, 0x32, 0x39,
  0x32, 0x31, 0x30, 0x30, 0x30, 0x32, 0x5a, 0x30, 0x6f, 0x31, 0x0b, 0x30,
  0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b,
  0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31,
  0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0d, 0x45, 0x78,
  0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x31,
  0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x09, 0x4e, 0x58,
  0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x31, 0x27, 0x30, 0x25, 0x06,
  0x03, 0x55, 0x04, 0x03, 0x0c, 0x1e, 0x4e, 0x58, 0x20, 0x53, 0x65, 0x63,
  0x75, 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x74,
  0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41,
  0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
  0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00,
  0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xa7, 0xa4, 0xd9,
  0xd0, 0x19, 0x84, 0x4e, 0xab, 0x8e, 0x08, 0xad, 0x30, 0xe6, 0x79, 0x46,
  0x46, 0xe2, 0xd3, 0x13, 0xc1, 0x69, 0xa9, 0x4a, 0xc9, 0xc8, 0x95, 0x54,
  0xa8, 0x76, 0x41, 0x63, 0x10, 0xc4, 0xe4, 0xfd, 0x08, 0x69, 0x7f, 0x89,
  0x79, 0x82, 0x62, 0xd7, 0x90, 0x73, 0x55, 0x06, 0x0d, 0x62, 0xec, 0x1b,
  0x2d, 0xaf, 0xf2, 0x39, 0x14, 0x47, 0x5b, 0x9d, 0x7a, 0xd2, 0xe3, 0xf9,
  0xae, 0x37, 0x49, 0xd0, 0xb8, 0x01, 0xf2, 0x1a, 0x84, 0x9a, 0x50, 0x37,
  0x4d, 0xd6, 0xed, 0x7c, 0x44, 0xef, 0xd1, 0xb8, 0x05, 0x4b, 0x3c, 0x05,
  0x59, 0x4a, 0xcd, 0xc1, 0xce, 0x6d, 0xb9, 0xbe, 0xb0, 0xc4, 0xe5, 0x44,
  0x02, 0xfd, 0xfa, 0x61, 0x3e, 0x59, 0x3e, 0x4b, 0x0f, 0xe6, 0x20, 0xda,
  0xf1, 0xca, 0xb5, 0x67, 0x52, 0x2b, 0x2e, 0x1b, 0xfc, 0xf1, 0xc6, 0x55,
  0x88, 0xf9, 0x28, 0xaa, 0xd9, 0x55, 0x6a, 0xc7, 0x61, 0x94, 0x24, 0x8d,
  0x63, 0xfb, 0xa6, 0x8a, 0x06, 0x21, 0xe2, 0x8e, 0xf7, 0xa8, 0x0b, 0x91,
  0x39, 0xff, 0x8d, 0xde, 0xb8, 0x0b, 0x16, 0x8a, 0xc6, 0xac, 0xe0, 0x61,
  0x69, 0x98, 0x4a, 0x90, 0xfd, 0x03, 0xe3, 0x38, 0x90, 0xc7, 0xe3, 0x13,
  0x40, 0x12, 0xc5, 0x44, 0x07, 0x44, 0x57, 0x43, 0xbb, 0xa4, 0x67, 0x72,
  0x20, 0xbb, 0x97, 0xe6, 0xa1, 0x32, 0xb2, 0x73, 0xf2, 0x8d, 0xe3, 0x23,
  0xdc, 0x06, 0xc0, 0x1f, 0xfc, 0xe3, 0x3a, 0xcc, 0x9c, 0xf8, 0x00, 0x87,
  0x39, 0x0d, 0x1e, 0x4d, 0x59, 0x15, 0x16, 0xe6, 0x63, 0x5b, 0x53, 0x6d,
  0x79, 0x2f, 0xb7, 0x5a, 0xcc, 0x37, 0xc9, 0x96, 0xff, 0x46, 0xac, 0xdd,
  0x44, 0x9f, 0x3a, 0xc8, 0x83, 0xeb, 0x1b, 0x67, 0xa0, 0x2d, 0xa8, 0x34,
  0x19, 0xf0, 0x5b, 0xe8, 0x59, 0xf7, 0xc9, 0x08, 0xab, 0x09, 0x71, 0x78,
  0x75, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x7b, 0x30, 0x79, 0x30, 0x09,
  0x06, 0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x2c, 0x06,
  0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x1f,
  0x16, 0x1d, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53, 0x4c, 0x20, 0x47, 0x65,
  0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x43, 0x65, 0x72, 0x74,
  0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x1d, 0x06, 0x03, 0x55,
  0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x8e, 0x6a, 0xb0, 0xfe, 0x49, 0xc5,
  0x6a, 0x96, 0x9e, 0xba, 0xb8, 0xb6, 0x58, 0xfc, 0x52, 0x7f, 0xab, 0x51,
  0xf2, 0x3a, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30,
  0x16, 0x80, 0x14, 0x1b, 0x8d, 0x06, 0xd9, 0x6b, 0xad, 0xee, 0x82, 0x24,
  0x26, 0x55, 0x9a, 0x1b, 0x03, 0x44, 0x92, 0x0a, 0x06, 0x92, 0x48, 0x30,
  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b,
  0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x18, 0x5a, 0x50, 0xb6, 0x44,
  0xba, 0x68, 0xac, 0x7f, 0x06, 0x0f, 0xbc, 0x1a, 0x58, 0x59, 0xf1, 0xf1,
  0xe3, 0xb8, 0x0d, 0x74, 0xdd, 0x74, 0x26, 0x6a, 0xea, 0xfc, 0xfe, 0x06,
  0x53, 0xe9, 0x80, 0xe3, 0x07, 0x83, 0x8a, 0xc9, 0xc9, 0xc0, 0x93, 0xb4,
  0xc2, 0x59, 0x71, 0xa7, 0x58, 0xac, 0x32, 0x0f, 0x32, 0x9c, 0x5b, 0x4d,
  0x53, 0xcb, 0xdc, 0x04, 0x00, 0x04, 0x27, 0x37, 0x2d, 0x11, 0x5b, 0xaa,
  0xf6, 0x45, 0x8a, 0xc4, 0x74, 0x2e, 0x47, 0x83, 0xb8, 0x5e, 0x3a, 0xc0,
  0x10, 0xaf, 0xc1, 0xd2, 0x61, 0x1c, 0x85, 0x31, 0x16, 0x74, 0x05, 0xf4,
  0xc6, 0xd8, 0x35, 0x83, 0x13, 0xca, 0x25, 0x5b, 0x22, 0xc6, 0x2c, 0x32,
  0x8d, 0x3a, 0x3f, 0x78, 0x79, 0x57, 0xbe, 0x97, 0x96, 0x90, 0x20, 0x7d,
  0xe5, 0xe6, 0xe6, 0x42, 0xde, 0xd3, 0xd4, 0xb4, 0x18, 0x34, 0x9d, 0xc3,
  0x95, 0x2d, 0xb2, 0x91, 0x1d, 0xfe, 0x3c, 0xee, 0x5c, 0xda, 0xdd, 0xd7,
  0xf5, 0x05, 0xf1, 0xbd, 0xa0, 0x2f, 0x0a, 0x03, 0x2e, 0x45, 0x26, 0x9c,
  0xac, 0x16, 0x59, 0x9a, 0x7f, 0xf2, 0x3a, 0x3e, 0xdb, 0x4b, 0x63, 0x58,
  0x38, 0x0b, 0x64, 0x5e, 0x24, 0x15, 0x92, 0xb5, 0xcf, 0x33, 0xe9, 0x61,
  0x1f, 0xb9, 0x33, 0xa1, 0x09, 0x41, 0x9f, 0x05, 0x11, 0xad, 0x07, 0x0b,
  0x60, 0x67, 0x1a, 0x4c, 0x6c, 0x93, 0x36, 0x90, 0x20, 0xac, 0xb3, 0x99,
  0x61, 0xa0, 0xda, 0xe5, 0x8d, 0x3f, 0x66, 0xd1, 0xf3, 0x91, 0x40, 0x60,
  0xcf, 0x97, 0xbb, 0x15, 0xb1, 0x81, 0x4e, 0xbf, 0xba, 0xef, 0x20, 0x36,
  0x6f, 0x00, 0x40, 0xa2, 0xa3, 0x24, 0x5c, 0x61, 0xd5, 0xa5, 0x64, 0xbf,
  0xbe, 0x29, 0xdf, 0x47, 0x4b, 0xc8, 0x76, 0x4f, 0x2e, 0x4c, 0x5c, 0xed,
  0x99, 0x26, 0xe8, 0xf1, 0x72, 0x5e, 0x9b, 0x86, 0x73, 0xda, 0xfb
};
static UINT ica_cert_der_len = 995;


/* Basic server certificate, no policies.
   Common Name: "NX Secure Device Certificate" */
static UCHAR test_server_cert_der[] = {
  0x30, 0x82, 0x03, 0xdb, 0x30, 0x82, 0x02, 0xc3, 0xa0, 0x03, 0x02, 0x01,
  0x02, 0x02, 0x02, 0x10, 0x00, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x6f, 0x31, 0x0b,
  0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
  0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41,
  0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0d, 0x45,
  0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x4c, 0x6f, 0x67, 0x69, 0x63,
  0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x09, 0x4e,
  0x58, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x31, 0x27, 0x30, 0x25,
  0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1e, 0x4e, 0x58, 0x20, 0x53, 0x65,
  0x63, 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6e,
  0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x43,
  0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x33, 0x33, 0x31, 0x32,
  0x31, 0x30, 0x39, 0x30, 0x39, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x33,
  0x32, 0x39, 0x32, 0x31, 0x30, 0x39, 0x30, 0x39, 0x5a, 0x30, 0x75, 0x31,
  0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
  0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43,
  0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16, 0x30,
  0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0d, 0x45, 0x78, 0x70, 0x72,
  0x65, 0x73, 0x73, 0x20, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x31, 0x12, 0x30,
  0x10, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x09, 0x4e, 0x58, 0x20, 0x53,
  0x65, 0x63, 0x75, 0x72, 0x65, 0x31, 0x25, 0x30, 0x23, 0x06, 0x03, 0x55,
  0x04, 0x03, 0x0c, 0x1c, 0x4e, 0x58, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72,
  0x65, 0x20, 0x44, 0x65, 0x76, 0x69, 0x63, 0x65, 0x20, 0x43, 0x65, 0x72,
  0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x82, 0x01, 0x22,
  0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
  0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a,
  0x02, 0x82, 0x01, 0x01, 0x00, 0xc4, 0x7e, 0xd4, 0xe3, 0xa2, 0x0c, 0x78,
  0xe6, 0x0f, 0xa5, 0x3c, 0x01, 0x9b, 0x01, 0xdf, 0x96, 0xf6, 0x8e, 0xa0,
  0x80, 0x4b, 0xb1, 0xc7, 0x20, 0x3c, 0xca, 0x81, 0x9a, 0xce, 0x08, 0x5f,
  0x70, 0x99, 0x8d, 0x44, 0x46, 0xbc, 0xf5, 0xb1, 0x80, 0x3c, 0xe0, 0xc9,
  0x09, 0x11, 0xb4, 0x07, 0x89, 0x5f, 0x06, 0x89, 0xec, 0xbe, 0xf8, 0x29,
  0x48, 0x40, 0x55, 0x60, 0x1d, 0x59, 0xb3, 0x7b, 0x84, 0x77, 0xc3, 0x34,
  0xf4, 0xd3, 0x51, 0x3e, 0x2f, 0x9d, 0x10, 0xbb, 0xaf, 0x47, 0xb2, 0xc5,
  0x78, 0x8a, 0x85, 0xea, 0xbb, 0xe5, 0xb3, 0x8a, 0x25, 0xaf, 0xd6, 0xb9,
  0xb3, 0x47, 0xf3, 0x5f, 0x7b, 0xc2, 0x69, 0xe3, 0x08, 0xf5, 0x45, 0xae,
  0x53, 0xb4, 0x79, 0x6e, 0xdd, 0xcf, 0xc0, 0x53, 0x81, 0x62, 0xd3, 0x2c,
  0xc9, 0x19, 0xcb, 0x5d, 0xfc, 0xa9, 0xd8, 0xa7, 0xab, 0x65, 0x52, 0x02,
  0x46, 0x56, 0xc0, 0x5b, 0xef, 0xee, 0x0a, 0xf1, 0x35, 0x87, 0xf7, 0x14,
  0xec, 0x1b, 0x77, 0x11, 0x81, 0x4d, 0xca, 0xdc, 0x55, 0x66, 0x40, 0xa4,
  0x04, 0xdc, 0x2a, 0x9f, 0xfe, 0x9f, 0x99, 0x4d, 0xb2, 0x5a, 0xcb, 0x58,
  0x97, 0x1d, 0xd4, 0x74, 0x16, 0xd0, 0x7e, 0x1d, 0x5e, 0x9b, 0xf7, 0xf3,
  0x5b, 0xd4, 0xf5, 0xde, 0xa5, 0x71, 0x36, 0x13, 0x7f, 0xea, 0xba, 0x0b,
  0x3e, 0xbd, 0xef, 0x7c, 0x34, 0x41, 0xe1, 0xb7, 0x99, 0x46, 0x9f, 0x81,
  0xc6, 0xcf, 0x72, 0x94, 0x65, 0x52, 0xf0, 0x88, 0x17, 0xf6, 0x00, 0xf4,
  0xd0, 0x9a, 0x66, 0xe7, 0x1e, 0xa5, 0xfd, 0x4b, 0x95, 0xf3, 0x0e, 0x0f,
  0x10, 0x60, 0x74, 0x54, 0xda, 0xb0, 0x91, 0x0a, 0x10, 0x07, 0x19, 0x30,
  0x71, 0x34, 0x5f, 0xe2, 0x1c, 0x08, 0x77, 0x2e, 0xbc, 0xa3, 0x13, 0x18,
  0x22, 0x5e, 0xf9, 0xe0, 0x67, 0x8e, 0xbc, 0xc0, 0x7d, 0x02, 0x03, 0x01,
  0x00, 0x01, 0xa3, 0x7b, 0x30, 0x79, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d,
  0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x2c, 0x06, 0x09, 0x60, 0x86, 0x48,
  0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x1f, 0x16, 0x1d, 0x4f, 0x70,
  0x65, 0x6e, 0x53, 0x53, 0x4c, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61,
  0x74, 0x65, 0x64, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
  0x61, 0x74, 0x65, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16,
  0x04, 0x14, 0x5c, 0xac, 0x85, 0x36, 0xd2, 0x6c, 0x5b, 0x71, 0xd0, 0x7e,
  0x78, 0xe6, 0x4b, 0xc7, 0x9e, 0x0b, 0x06, 0xaa, 0x70, 0x8b, 0x30, 0x1f,
  0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x8e,
  0x6a, 0xb0, 0xfe, 0x49, 0xc5, 0x6a, 0x96, 0x9e, 0xba, 0xb8, 0xb6, 0x58,
  0xfc, 0x52, 0x7f, 0xab, 0x51, 0xf2, 0x3a, 0x30, 0x0d, 0x06, 0x09, 0x2a,
  0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82,
  0x01, 0x01, 0x00, 0x58, 0x39, 0x3d, 0xc9, 0xcf, 0x4a, 0x8b, 0x15, 0x82,
  0xcf, 0xce, 0x12, 0xb8, 0x4f, 0x6e, 0x83, 0x71, 0x9b, 0x52, 0xeb, 0xe9,
  0xdc, 0xe4, 0xe1, 0x77, 0x3b, 0x74, 0xd7, 0xc5, 0xd7, 0x50, 0x9a, 0xb9,
  0x1f, 0x0a, 0x27, 0x0a, 0x9b, 0x19, 0xf0, 0x2d, 0x86, 0xf7, 0x71, 0xec,
  0x7c, 0x87, 0x65, 0x19, 0xd0, 0x86, 0xe2, 0xf1, 0xd5, 0x22, 0x21, 0xe3,
  0xbf, 0x0d, 0xcb, 0x42, 0x7f, 0x70, 0xe5, 0x13, 0x96, 0x6d, 0x5b, 0xc1,
  0x7e, 0xd0, 0x34, 0x82, 0xaf, 0x29, 0xed, 0x7f, 0x6e, 0xc6, 0x7f, 0x8b,
  0xe8, 0x20, 0xc6, 0x39, 0x51, 0x9b, 0xec, 0x15, 0xa8, 0x9a, 0x63, 0xa5,
  0x92, 0x4a, 0xbc, 0x45, 0xf0, 0x86, 0xef, 0x09, 0xc0, 0xe4, 0x32, 0x3c,
  0x7a, 0x62, 0x51, 0x67, 0x0b, 0x0b, 0x8a, 0x2e, 0x07, 0xd5, 0x7c, 0xd5,
  0xd0, 0x4f, 0x93, 0x1d, 0x2d, 0x00, 0x6d, 0x99, 0x89, 0x55, 0xb3, 0x99,
  0x98, 0x1b, 0x13, 0x60, 0xb4, 0x80, 0x57, 0xbe, 0xe3, 0x25, 0xb6, 0x9a,
  0x75, 0x95, 0x3d, 0xba, 0xe5, 0x48, 0xa6, 0x3b, 0x1c, 0xd7, 0x50, 0x90,
  0x19, 0x4c, 0xf5, 0x22, 0x94, 0x7f, 0x79, 0xd5, 0x5e, 0x5a, 0xfb, 0x29,
  0x34, 0xf8, 0xd7, 0xf5, 0x2e, 0x95, 0x81, 0xb7, 0x2c, 0x8f, 0x2f, 0xcf,
  0xdd, 0xc4, 0xcf, 0x1b, 0x2e, 0x2b, 0xe8, 0x4d, 0x92, 0xf6, 0x8f, 0xba,
  0x08, 0x1a, 0x8a, 0x13, 0x2c, 0x2d, 0x38, 0xce, 0xfe, 0xa5, 0x59, 0xc5,
  0xea, 0x3a, 0x07, 0x8b, 0xf9, 0x8d, 0x33, 0x25, 0xc0, 0x4e, 0x75, 0x51,
  0xfc, 0xd1, 0x12, 0xec, 0x85, 0xb1, 0xb5, 0xf4, 0xc2, 0xb8, 0x05, 0x3c,
  0x00, 0x4a, 0x1b, 0xab, 0xb2, 0xab, 0x69, 0x58, 0x33, 0x93, 0xf8, 0x47,
  0x12, 0x75, 0xc2, 0x3a, 0x82, 0xe1, 0x2d, 0x95, 0xa9, 0x9c, 0xb9, 0xe3,
  0x3d, 0x29, 0x93, 0x65, 0xa1, 0x79, 0xee
};
static UINT test_server_cert_der_len = 991;

static UCHAR test_server_cert_key_der[] = {
  0x30, 0x82, 0x04, 0xa3, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00,
  0xc4, 0x7e, 0xd4, 0xe3, 0xa2, 0x0c, 0x78, 0xe6, 0x0f, 0xa5, 0x3c, 0x01,
  0x9b, 0x01, 0xdf, 0x96, 0xf6, 0x8e, 0xa0, 0x80, 0x4b, 0xb1, 0xc7, 0x20,
  0x3c, 0xca, 0x81, 0x9a, 0xce, 0x08, 0x5f, 0x70, 0x99, 0x8d, 0x44, 0x46,
  0xbc, 0xf5, 0xb1, 0x80, 0x3c, 0xe0, 0xc9, 0x09, 0x11, 0xb4, 0x07, 0x89,
  0x5f, 0x06, 0x89, 0xec, 0xbe, 0xf8, 0x29, 0x48, 0x40, 0x55, 0x60, 0x1d,
  0x59, 0xb3, 0x7b, 0x84, 0x77, 0xc3, 0x34, 0xf4, 0xd3, 0x51, 0x3e, 0x2f,
  0x9d, 0x10, 0xbb, 0xaf, 0x47, 0xb2, 0xc5, 0x78, 0x8a, 0x85, 0xea, 0xbb,
  0xe5, 0xb3, 0x8a, 0x25, 0xaf, 0xd6, 0xb9, 0xb3, 0x47, 0xf3, 0x5f, 0x7b,
  0xc2, 0x69, 0xe3, 0x08, 0xf5, 0x45, 0xae, 0x53, 0xb4, 0x79, 0x6e, 0xdd,
  0xcf, 0xc0, 0x53, 0x81, 0x62, 0xd3, 0x2c, 0xc9, 0x19, 0xcb, 0x5d, 0xfc,
  0xa9, 0xd8, 0xa7, 0xab, 0x65, 0x52, 0x02, 0x46, 0x56, 0xc0, 0x5b, 0xef,
  0xee, 0x0a, 0xf1, 0x35, 0x87, 0xf7, 0x14, 0xec, 0x1b, 0x77, 0x11, 0x81,
  0x4d, 0xca, 0xdc, 0x55, 0x66, 0x40, 0xa4, 0x04, 0xdc, 0x2a, 0x9f, 0xfe,
  0x9f, 0x99, 0x4d, 0xb2, 0x5a, 0xcb, 0x58, 0x97, 0x1d, 0xd4, 0x74, 0x16,
  0xd0, 0x7e, 0x1d, 0x5e, 0x9b, 0xf7, 0xf3, 0x5b, 0xd4, 0xf5, 0xde, 0xa5,
  0x71, 0x36, 0x13, 0x7f, 0xea, 0xba, 0x0b, 0x3e, 0xbd, 0xef, 0x7c, 0x34,
  0x41, 0xe1, 0xb7, 0x99, 0x46, 0x9f, 0x81, 0xc6, 0xcf, 0x72, 0x94, 0x65,
  0x52, 0xf0, 0x88, 0x17, 0xf6, 0x00, 0xf4, 0xd0, 0x9a, 0x66, 0xe7, 0x1e,
  0xa5, 0xfd, 0x4b, 0x95, 0xf3, 0x0e, 0x0f, 0x10, 0x60, 0x74, 0x54, 0xda,
  0xb0, 0x91, 0x0a, 0x10, 0x07, 0x19, 0x30, 0x71, 0x34, 0x5f, 0xe2, 0x1c,
  0x08, 0x77, 0x2e, 0xbc, 0xa3, 0x13, 0x18, 0x22, 0x5e, 0xf9, 0xe0, 0x67,
  0x8e, 0xbc, 0xc0, 0x7d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01,
  0x00, 0x20, 0x0c, 0x53, 0xaa, 0xa0, 0xe6, 0x89, 0xdd, 0x74, 0x15, 0xce,
  0x18, 0xb0, 0xf0, 0x78, 0x48, 0x46, 0x04, 0x73, 0x37, 0x19, 0xa1, 0x70,
  0x49, 0xd8, 0xc0, 0x6a, 0xad, 0x16, 0x07, 0x95, 0x91, 0x66, 0xe9, 0xfc,
  0x85, 0xd1, 0x11, 0xfd, 0x96, 0x5d, 0xd7, 0x87, 0xd2, 0x7b, 0xd9, 0xb2,
  0x14, 0xfc, 0xb3, 0xb3, 0x51, 0x32, 0xc0, 0x84, 0xf3, 0x2c, 0xd2, 0xff,
  0xef, 0x29, 0x8f, 0x35, 0x89, 0x20, 0x83, 0x6d, 0x22, 0xb5, 0x48, 0x9d,
  0xec, 0xe4, 0x20, 0x33, 0x8c, 0x5e, 0x14, 0x51, 0x52, 0xdc, 0xbd, 0x04,
  0xd1, 0x0a, 0xa0, 0xe2, 0xda, 0x4c, 0xb8, 0xa7, 0xe7, 0x0e, 0xc8, 0x29,
  0xfd, 0xa4, 0x72, 0xe2, 0xbd, 0xb6, 0x4b, 0x5c, 0x28, 0x78, 0xda, 0x09,
  0x74, 0x12, 0x0b, 0x5b, 0x53, 0x52, 0x0c, 0x01, 0x54, 0xf7, 0x69, 0x0c,
  0xf6, 0x45, 0xb9, 0x79, 0x77, 0x61, 0xfa, 0x23, 0x36, 0x8e, 0x54, 0x0f,
  0x19, 0x63, 0xd4, 0x84, 0xd7, 0xea, 0xc5, 0x3e, 0x8c, 0x4f, 0x2e, 0x1d,
  0x24, 0xd6, 0x53, 0x15, 0x47, 0xcd, 0xb6, 0x43, 0x67, 0x94, 0x85, 0x43,
  0xe1, 0x90, 0x8b, 0xef, 0x19, 0x88, 0xcf, 0xa9, 0x1c, 0x50, 0xce, 0x33,
  0x11, 0x2c, 0x61, 0x92, 0xf4, 0xc9, 0xa0, 0xa4, 0x34, 0xdc, 0x7e, 0xea,
  0xb5, 0x27, 0x0b, 0x35, 0xb0, 0x83, 0x22, 0x85, 0x60, 0x1f, 0xa0, 0xaa,
  0x46, 0x01, 0xd7, 0x60, 0x5f, 0x8f, 0x1a, 0x75, 0x8d, 0x65, 0x7e, 0xf2,
  0xbc, 0xb0, 0xf4, 0xaa, 0x45, 0x36, 0x09, 0x01, 0x3d, 0x1e, 0x6a, 0x9c,
  0x51, 0xcf, 0x71, 0xe6, 0x73, 0x4e, 0x45, 0xe0, 0x36, 0x4c, 0xe0, 0xca,
  0x79, 0x6c, 0x62, 0x32, 0xca, 0xfd, 0x61, 0xb2, 0x3b, 0x88, 0xc7, 0x9c,
  0x7a, 0x5f, 0x87, 0x66, 0x6e, 0x04, 0xcc, 0x71, 0x50, 0x2e, 0x21, 0x37,
  0x2e, 0x33, 0xef, 0x5e, 0x9d, 0x02, 0x81, 0x81, 0x00, 0xf2, 0x58, 0xc2,
  0xc5, 0x96, 0xec, 0x49, 0x0c, 0x8b, 0x4f, 0x60, 0x8b, 0x31, 0xd7, 0x66,
  0xe3, 0x7e, 0x0e, 0xd1, 0xce, 0x93, 0x89, 0xea, 0x34, 0xd3, 0x93, 0xa2,
  0xed, 0xfb, 0x38, 0xa9, 0xc7, 0x99, 0x5b, 0xae, 0x1b, 0x69, 0xd8, 0x9d,
  0x70, 0x6b, 0x91, 0x93, 0x42, 0x03, 0x7c, 0xd9, 0x90, 0xa3, 0xec, 0xa5,
  0x9a, 0xf1, 0xc4, 0xd6, 0x97, 0x64, 0x08, 0x2b, 0xe8, 0x9c, 0x7b, 0xfa,
  0xeb, 0xd3, 0x4c, 0x3c, 0x14, 0x6c, 0xc9, 0x7d, 0x0b, 0x60, 0xe2, 0x9e,
  0x08, 0x66, 0xde, 0xd2, 0xc5, 0x41, 0xd8, 0xa7, 0x26, 0x04, 0x78, 0x73,
  0x02, 0x58, 0x9f, 0xb6, 0x0c, 0x0e, 0x54, 0x06, 0x50, 0xf3, 0x45, 0xd4,
  0xf2, 0x76, 0x50, 0x95, 0xe2, 0x5c, 0xea, 0x50, 0x22, 0xe2, 0x0d, 0xec,
  0x68, 0x3f, 0x51, 0xd3, 0x18, 0xe8, 0x29, 0x30, 0x21, 0xf1, 0xfa, 0x12,
  0x7a, 0xfa, 0xc4, 0x4b, 0xa7, 0x02, 0x81, 0x81, 0x00, 0xcf, 0x90, 0xc8,
  0x24, 0xed, 0xe9, 0x04, 0x5b, 0x4a, 0x76, 0xdc, 0xfb, 0xf8, 0x70, 0x43,
  0x0e, 0xf6, 0x9b, 0x68, 0x2c, 0x5d, 0x5b, 0x9e, 0x27, 0x80, 0x0e, 0x2d,
  0x66, 0x5f, 0x51, 0x70, 0xcb, 0xfb, 0x70, 0x25, 0x96, 0x06, 0xa5, 0x74,
  0x53, 0xaf, 0x45, 0x37, 0xbd, 0x4f, 0x22, 0xd9, 0x79, 0xef, 0xd3, 0x6d,
  0x33, 0xbe, 0xd4, 0x34, 0x82, 0x31, 0x50, 0x12, 0xab, 0x64, 0x5f, 0x45,
  0x0e, 0x90, 0xfd, 0x9c, 0x7f, 0xdb, 0xa1, 0xbe, 0x83, 0xbf, 0x50, 0x21,
  0x62, 0xb3, 0x90, 0x1c, 0x36, 0xf0, 0x44, 0x32, 0xca, 0xa9, 0xac, 0x30,
  0xcd, 0x27, 0x50, 0xf0, 0xed, 0x25, 0xf6, 0x35, 0x62, 0xd5, 0x8d, 0x8c,
  0x54, 0xfc, 0xbb, 0xd0, 0xb7, 0x53, 0x09, 0x7f, 0xed, 0x1b, 0xda, 0xcd,
  0x96, 0x2e, 0xfc, 0x73, 0xdd, 0xe6, 0x1b, 0xb2, 0x00, 0xf7, 0x4c, 0xd7,
  0xf9, 0x19, 0xdc, 0x47, 0x3b, 0x02, 0x81, 0x80, 0x2e, 0x37, 0x43, 0x1d,
  0x8f, 0x44, 0x8c, 0x41, 0xba, 0x27, 0x6f, 0x0f, 0xdc, 0x77, 0x69, 0x85,
  0xa4, 0xba, 0x8a, 0xc4, 0x4c, 0x5a, 0x96, 0xb1, 0x70, 0x4f, 0xcd, 0x58,
  0x78, 0xfa, 0x3b, 0x56, 0x77, 0x26, 0x86, 0xb3, 0x6f, 0xa2, 0x01, 0x94,
  0x38, 0xcf, 0x50, 0x37, 0xdc, 0x96, 0x68, 0x9f, 0x2e, 0xc3, 0xa8, 0x69,
  0x3e, 0x05, 0xfd, 0xae, 0x6d, 0x43, 0x29, 0xac, 0x78, 0x7b, 0x24, 0x44,
  0xe8, 0xcc, 0xb7, 0x00, 0x66, 0x26, 0x9e, 0x94, 0x16, 0xeb, 0xe0, 0x9b,
  0x55, 0x92, 0xd4, 0xbb, 0x0d, 0x6d, 0x95, 0xa2, 0xa8, 0x63, 0x97, 0xfb,
  0x30, 0x8f, 0x74, 0x96, 0x23, 0xfd, 0x5e, 0x1e, 0xfd, 0xe5, 0xa9, 0x50,
  0x7b, 0xc3, 0xae, 0x71, 0xb6, 0xaa, 0x70, 0x91, 0xd6, 0x6e, 0x35, 0x51,
  0x44, 0x12, 0x04, 0xa1, 0xd1, 0x54, 0x59, 0x7b, 0x7f, 0xbb, 0xe2, 0xde,
  0x55, 0x08, 0x2e, 0x2d, 0x02, 0x81, 0x81, 0x00, 0x9c, 0x64, 0xd6, 0xa9,
  0x1c, 0xa9, 0x8a, 0x22, 0xcf, 0x04, 0xa8, 0x95, 0x22, 0x28, 0x54, 0x1e,
  0x9e, 0x29, 0x92, 0x60, 0x7b, 0x27, 0x61, 0x0f, 0x1a, 0x29, 0x94, 0x83,
  0xa2, 0x26, 0x56, 0xfb, 0x1b, 0x44, 0xf0, 0xcd, 0x0d, 0xcc, 0xf4, 0xcd,
  0x69, 0x2e, 0x9a, 0x45, 0x05, 0xaf, 0x98, 0x75, 0x8c, 0x02, 0x9e, 0x31,
  0x73, 0x03, 0xa9, 0x5c, 0xbf, 0x93, 0x39, 0xbd, 0xf2, 0x2e, 0xe6, 0x75,
  0x87, 0x41, 0xcf, 0xfd, 0x76, 0x9b, 0x74, 0x55, 0x08, 0x7d, 0x73, 0xea,
  0x4e, 0xa9, 0xb2, 0xd8, 0xa2, 0x48, 0x80, 0x8c, 0xbb, 0x33, 0x86, 0xc1,
  0xcd, 0x71, 0xeb, 0x56, 0x84, 0x57, 0xf2, 0xf9, 0xb9, 0x36, 0xa2, 0x1a,
  0x17, 0x23, 0xdc, 0xab, 0x84, 0xe1, 0x8f, 0x86, 0x34, 0x8a, 0xb4, 0x85,
  0x08, 0x7a, 0x27, 0x43, 0x76, 0xf2, 0x3f, 0x39, 0x03, 0x1c, 0xdf, 0x4e,
  0x4d, 0xf1, 0xef, 0xa9, 0x02, 0x81, 0x80, 0x5c, 0x2d, 0x0a, 0x0d, 0x51,
  0x48, 0xcd, 0x38, 0x64, 0xf3, 0x7a, 0xfd, 0x1a, 0x19, 0x42, 0x28, 0x68,
  0xca, 0xda, 0x98, 0x2b, 0x46, 0xbb, 0x85, 0xdd, 0x55, 0x3d, 0xd8, 0x61,
  0x7d, 0xc4, 0x90, 0x9d, 0xee, 0xe8, 0xb2, 0xc8, 0x85, 0xc9, 0x43, 0x14,
  0xf7, 0x74, 0x01, 0xeb, 0x03, 0x0b, 0x7f, 0x24, 0x13, 0x99, 0x04, 0xff,
  0x95, 0xf0, 0x08, 0x45, 0x76, 0xce, 0x00, 0xe8, 0xc5, 0x76, 0x34, 0xf9,
  0x91, 0xa0, 0xc8, 0x83, 0xa9, 0x78, 0x87, 0x1d, 0xac, 0xc9, 0x66, 0x4d,
  0x90, 0x46, 0x4e, 0x99, 0xef, 0xdd, 0x16, 0xa9, 0xc9, 0x43, 0xd6, 0xbf,
  0xa1, 0x6b, 0x33, 0x8b, 0x68, 0x1d, 0x25, 0xd2, 0x95, 0x0d, 0xd0, 0x4d,
  0xe2, 0xd9, 0x1e, 0x9c, 0xe0, 0x4a, 0xad, 0x1e, 0xda, 0xfd, 0x0d, 0xc1,
  0xf7, 0x9c, 0xa7, 0x55, 0xb1, 0x70, 0xad, 0x33, 0x15, 0x1e, 0xe5, 0xc0,
  0x44, 0x78, 0xd1
};
static UINT test_server_cert_key_der_len = 1191;

/* Policy certificate with key usage extensions.
   Common Name: "certificate_with_policies" */
static UCHAR test_device_cert_der[] = {
  0x30, 0x82, 0x04, 0x14, 0x30, 0x82, 0x02, 0xfc, 0xa0, 0x03, 0x02, 0x01,
  0x02, 0x02, 0x02, 0x10, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
  0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x6f, 0x31, 0x0b,
  0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
  0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41,
  0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0d, 0x45,
  0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x4c, 0x6f, 0x67, 0x69, 0x63,
  0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x09, 0x4e,
  0x58, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x31, 0x27, 0x30, 0x25,
  0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1e, 0x4e, 0x58, 0x20, 0x53, 0x65,
  0x63, 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6e,
  0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x43,
  0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x37, 0x31, 0x31, 0x33, 0x30, 0x30,
  0x30, 0x31, 0x36, 0x34, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x37, 0x31, 0x31,
  0x32, 0x38, 0x30, 0x30, 0x31, 0x36, 0x34, 0x30, 0x5a, 0x30, 0x74, 0x31,
  0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53,
  0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43,
  0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16, 0x30,
  0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0d, 0x45, 0x78, 0x70, 0x72,
  0x65, 0x73, 0x73, 0x20, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x31, 0x14, 0x30,
  0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x4e, 0x65, 0x74, 0x58,
  0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x31, 0x22, 0x30, 0x20, 0x06,
  0x03, 0x55, 0x04, 0x03, 0x0c, 0x19, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66,
  0x69, 0x63, 0x61, 0x74, 0x65, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x70,
  0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65, 0x73, 0x30, 0x82, 0x01, 0x22, 0x30,
  0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01,
  0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02,
  0x82, 0x01, 0x01, 0x00, 0xda, 0x31, 0xa1, 0xae, 0x67, 0xaf, 0x9c, 0x50,
  0x5f, 0x1b, 0xd4, 0xce, 0x6d, 0x3c, 0x3c, 0xa6, 0xd2, 0x41, 0x86, 0x7a,
  0xed, 0x81, 0x65, 0x82, 0x3f, 0xa1, 0x54, 0x89, 0xba, 0x4d, 0x7a, 0x9e,
  0xab, 0x99, 0x24, 0x23, 0x19, 0xf8, 0xb4, 0x83, 0xe1, 0xb0, 0x08, 0x7b,
  0x6f, 0x02, 0x7d, 0x80, 0x2e, 0xd9, 0xb5, 0xe1, 0xb2, 0x13, 0x3b, 0x23,
  0x32, 0xc8, 0x0b, 0xad, 0xc4, 0xac, 0x95, 0xa6, 0x82, 0x0e, 0xec, 0x62,
  0xfa, 0x7f, 0xf5, 0x2c, 0xc7, 0xe6, 0x4e, 0x28, 0x30, 0xb6, 0x66, 0x5d,
  0xa8, 0x28, 0xeb, 0xbe, 0xfd, 0xd3, 0xa7, 0xc5, 0xcc, 0x13, 0x3b, 0x50,
  0xff, 0x48, 0x2f, 0x81, 0xb8, 0x8d, 0x32, 0x97, 0x71, 0xab, 0xd0, 0x1b,
  0xe4, 0xb5, 0x80, 0x87, 0x16, 0xdb, 0x50, 0x35, 0xef, 0x5d, 0x46, 0x32,
  0xdd, 0x29, 0x79, 0xb9, 0x8f, 0xdc, 0xcb, 0x6a, 0x50, 0x46, 0xa2, 0x20,
  0xd8, 0xc3, 0x44, 0x8a, 0xd7, 0x5d, 0xc2, 0xe3, 0x0d, 0xc3, 0x33, 0xd3,
  0x23, 0xc7, 0x11, 0x21, 0xde, 0x34, 0xac, 0xb0, 0x9b, 0x4e, 0xdc, 0x4c,
  0x5e, 0xf8, 0x1d, 0xef, 0x0f, 0x28, 0x79, 0x33, 0xf6, 0x8a, 0xfe, 0x6e,
  0xb9, 0xd5, 0x49, 0xf0, 0x1f, 0x57, 0xca, 0x92, 0xa6, 0x93, 0x57, 0x51,
  0x5c, 0xf8, 0x54, 0x9b, 0xf0, 0x46, 0x3a, 0x10, 0xf5, 0x6f, 0x85, 0xb7,
  0x36, 0x5a, 0xfd, 0xda, 0x17, 0x2c, 0xb4, 0x22, 0x82, 0xe1, 0xd6, 0xf1,
  0x06, 0x2b, 0x22, 0x94, 0x72, 0xd2, 0xcc, 0x84, 0x6f, 0x53, 0x41, 0xfb,
  0xc9, 0x5f, 0xc8, 0x1e, 0x16, 0x57, 0x29, 0x40, 0x73, 0x3b, 0xc8, 0xae,
  0x06, 0x3e, 0x7b, 0xa7, 0x2a, 0x41, 0x8d, 0x96, 0xc3, 0xfd, 0xa2, 0x31,
  0x64, 0x60, 0xf1, 0x1d, 0x0a, 0xa3, 0x3b, 0xb3, 0x42, 0x2c, 0x2a, 0x0c,
  0x59, 0x47, 0x19, 0x0f, 0x8a, 0xc0, 0x7a, 0x9d, 0x02, 0x03, 0x01, 0x00,
  0x01, 0xa3, 0x81, 0xb4, 0x30, 0x81, 0xb1, 0x30, 0x09, 0x06, 0x03, 0x55,
  0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x11, 0x06, 0x09, 0x60, 0x86,
  0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x06,
  0x40, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02,
  0x05, 0xe0, 0x30, 0x2c, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
  0x42, 0x01, 0x0d, 0x04, 0x1f, 0x16, 0x1d, 0x4f, 0x70, 0x65, 0x6e, 0x53,
  0x53, 0x4c, 0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64,
  0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
  0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x98,
  0x0c, 0xd6, 0x1c, 0x08, 0x75, 0x6d, 0x49, 0x3f, 0xa4, 0xe9, 0x2d, 0xf9,
  0xd1, 0x70, 0x1a, 0xd7, 0xef, 0xc6, 0x05, 0x30, 0x1f, 0x06, 0x03, 0x55,
  0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 0x8e, 0x6a, 0xb0, 0xfe,
  0x49, 0xc5, 0x6a, 0x96, 0x9e, 0xba, 0xb8, 0xb6, 0x58, 0xfc, 0x52, 0x7f,
  0xab, 0x51, 0xf2, 0x3a, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01,
  0x01, 0xff, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
  0x05, 0x07, 0x03, 0x08, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86,
  0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00,
  0x71, 0x9f, 0xcd, 0x22, 0x0c, 0xc1, 0x2d, 0x31, 0xfb, 0x30, 0x29, 0x67,
  0x66, 0xd6, 0x1f, 0xbd, 0x4c, 0x37, 0xdc, 0xca, 0x0f, 0xf9, 0x59, 0xe8,
  0xb7, 0xaf, 0xcc, 0x2a, 0x95, 0x13, 0xc4, 0x47, 0x70, 0x6e, 0xde, 0xf0,
  0xbb, 0x2f, 0x58, 0x1f, 0xab, 0xe5, 0x53, 0x78, 0xa5, 0xe4, 0xaf, 0x65,
  0xb6, 0xad, 0x99, 0x4d, 0xa1, 0x5a, 0x11, 0x21, 0x19, 0x29, 0x4a, 0xb9,
  0x7e, 0x7f, 0xce, 0xb6, 0x63, 0x0c, 0x57, 0x3c, 0x04, 0x62, 0x07, 0x8c,
  0x3a, 0x84, 0x60, 0x6d, 0x36, 0x6a, 0xeb, 0xd3, 0xbe, 0x06, 0x78, 0xd0,
  0x2c, 0x2b, 0xa8, 0xef, 0x06, 0x5c, 0xd5, 0x76, 0x0a, 0x15, 0x88, 0x36,
  0x77, 0x34, 0x8f, 0x40, 0x81, 0xad, 0xfd, 0xa2, 0x34, 0x6d, 0xf0, 0xd7,
  0xe9, 0x12, 0x49, 0x62, 0x1a, 0x38, 0x4f, 0x9a, 0xbd, 0x2d, 0x3c, 0x7a,
  0xec, 0x2a, 0x53, 0xbf, 0x9b, 0x6f, 0x6f, 0x58, 0x30, 0xcf, 0x09, 0xa6,
  0x3c, 0x84, 0xe4, 0xe2, 0x27, 0x25, 0x58, 0x9e, 0xab, 0x43, 0x88, 0x9c,
  0xc7, 0xe2, 0xac, 0xff, 0xd5, 0x73, 0x7a, 0xf9, 0xf3, 0x5d, 0x09, 0x40,
  0xcc, 0x6b, 0x9e, 0x97, 0x35, 0x83, 0x1d, 0xb8, 0x0e, 0xd6, 0x1a, 0xbb,
  0xa1, 0x9d, 0x7f, 0x54, 0x77, 0x72, 0x66, 0x0f, 0x62, 0x94, 0xbb, 0x9e,
  0xf6, 0x2e, 0xb1, 0x68, 0x5f, 0xb4, 0x73, 0x85, 0x92, 0x3d, 0x97, 0xd3,
  0xd1, 0x1a, 0x5d, 0x56, 0xb4, 0x0e, 0x92, 0x99, 0x61, 0x5f, 0x56, 0xf3,
  0xf4, 0xc4, 0xec, 0xfa, 0xde, 0x71, 0xee, 0x47, 0xaf, 0xb5, 0x36, 0x6d,
  0x01, 0xcf, 0xc8, 0xc6, 0x93, 0x65, 0x7a, 0x1e, 0x1f, 0x1b, 0x1f, 0xf2,
  0xf7, 0x0e, 0xd9, 0x21, 0x61, 0xf3, 0x39, 0xf3, 0xa9, 0x1c, 0x8a, 0x3d,
  0x90, 0x0c, 0x49, 0x85, 0x69, 0x08, 0xc1, 0x3e, 0x1d, 0xbb, 0x63, 0xa6,
  0xd8, 0x57, 0xe6, 0x00
};
static UINT test_device_cert_der_len = 1048;

static UCHAR test_device_cert_key_der[] = {
  0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00,
  0xda, 0x31, 0xa1, 0xae, 0x67, 0xaf, 0x9c, 0x50, 0x5f, 0x1b, 0xd4, 0xce,
  0x6d, 0x3c, 0x3c, 0xa6, 0xd2, 0x41, 0x86, 0x7a, 0xed, 0x81, 0x65, 0x82,
  0x3f, 0xa1, 0x54, 0x89, 0xba, 0x4d, 0x7a, 0x9e, 0xab, 0x99, 0x24, 0x23,
  0x19, 0xf8, 0xb4, 0x83, 0xe1, 0xb0, 0x08, 0x7b, 0x6f, 0x02, 0x7d, 0x80,
  0x2e, 0xd9, 0xb5, 0xe1, 0xb2, 0x13, 0x3b, 0x23, 0x32, 0xc8, 0x0b, 0xad,
  0xc4, 0xac, 0x95, 0xa6, 0x82, 0x0e, 0xec, 0x62, 0xfa, 0x7f, 0xf5, 0x2c,
  0xc7, 0xe6, 0x4e, 0x28, 0x30, 0xb6, 0x66, 0x5d, 0xa8, 0x28, 0xeb, 0xbe,
  0xfd, 0xd3, 0xa7, 0xc5, 0xcc, 0x13, 0x3b, 0x50, 0xff, 0x48, 0x2f, 0x81,
  0xb8, 0x8d, 0x32, 0x97, 0x71, 0xab, 0xd0, 0x1b, 0xe4, 0xb5, 0x80, 0x87,
  0x16, 0xdb, 0x50, 0x35, 0xef, 0x5d, 0x46, 0x32, 0xdd, 0x29, 0x79, 0xb9,
  0x8f, 0xdc, 0xcb, 0x6a, 0x50, 0x46, 0xa2, 0x20, 0xd8, 0xc3, 0x44, 0x8a,
  0xd7, 0x5d, 0xc2, 0xe3, 0x0d, 0xc3, 0x33, 0xd3, 0x23, 0xc7, 0x11, 0x21,
  0xde, 0x34, 0xac, 0xb0, 0x9b, 0x4e, 0xdc, 0x4c, 0x5e, 0xf8, 0x1d, 0xef,
  0x0f, 0x28, 0x79, 0x33, 0xf6, 0x8a, 0xfe, 0x6e, 0xb9, 0xd5, 0x49, 0xf0,
  0x1f, 0x57, 0xca, 0x92, 0xa6, 0x93, 0x57, 0x51, 0x5c, 0xf8, 0x54, 0x9b,
  0xf0, 0x46, 0x3a, 0x10, 0xf5, 0x6f, 0x85, 0xb7, 0x36, 0x5a, 0xfd, 0xda,
  0x17, 0x2c, 0xb4, 0x22, 0x82, 0xe1, 0xd6, 0xf1, 0x06, 0x2b, 0x22, 0x94,
  0x72, 0xd2, 0xcc, 0x84, 0x6f, 0x53, 0x41, 0xfb, 0xc9, 0x5f, 0xc8, 0x1e,
  0x16, 0x57, 0x29, 0x40, 0x73, 0x3b, 0xc8, 0xae, 0x06, 0x3e, 0x7b, 0xa7,
  0x2a, 0x41, 0x8d, 0x96, 0xc3, 0xfd, 0xa2, 0x31, 0x64, 0x60, 0xf1, 0x1d,
  0x0a, 0xa3, 0x3b, 0xb3, 0x42, 0x2c, 0x2a, 0x0c, 0x59, 0x47, 0x19, 0x0f,
  0x8a, 0xc0, 0x7a, 0x9d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x02, 0x82, 0x01,
  0x00, 0x39, 0xd7, 0x20, 0x52, 0x18, 0x60, 0x60, 0x22, 0x9a, 0x23, 0xc9,
  0x94, 0xf3, 0x36, 0x1d, 0xa9, 0xe7, 0x60, 0xc1, 0x62, 0x82, 0xe5, 0x63,
  0x60, 0x54, 0xb7, 0xd2, 0xae, 0x33, 0xf9, 0xe8, 0x00, 0x79, 0xe2, 0xbd,
  0xc6, 0xa4, 0x52, 0xde, 0x9f, 0x7b, 0x4b, 0x6b, 0xe4, 0x34, 0xb8, 0x47,
  0x46, 0x9c, 0xa4, 0xcf, 0xe7, 0x45, 0x8a, 0x7d, 0x89, 0xc6, 0x23, 0x6b,
  0x9d, 0x23, 0xde, 0xd0, 0x48, 0xf4, 0x7f, 0x3a, 0x40, 0xbe, 0xc0, 0xfe,
  0xe0, 0x61, 0x19, 0x77, 0x2c, 0x86, 0x45, 0x43, 0xfb, 0x9d, 0xe1, 0x43,
  0x25, 0x3d, 0x2a, 0x47, 0x76, 0x52, 0xb3, 0xe2, 0x6c, 0x85, 0x4f, 0xc0,
  0x70, 0x35, 0xd9, 0x10, 0x49, 0x3f, 0x33, 0xd9, 0x96, 0x1b, 0x59, 0xd5,
  0xf9, 0x79, 0xa0, 0xa7, 0xb1, 0xb4, 0x83, 0x58, 0x61, 0x91, 0x69, 0x36,
  0x40, 0x6f, 0x97, 0x8b, 0x40, 0xe2, 0x88, 0xe6, 0xdf, 0x2a, 0xbe, 0xf6,
  0xfe, 0xe7, 0xc6, 0xea, 0xdc, 0xbe, 0x91, 0x39, 0xe5, 0x3a, 0x8b, 0x6c,
  0x3b, 0x67, 0x98, 0x7a, 0xc9, 0x0e, 0xd4, 0xac, 0xd3, 0xad, 0x2c, 0xf3,
  0xa4, 0xdc, 0x8e, 0x48, 0xc8, 0x8e, 0x9c, 0x0d, 0x26, 0x69, 0x2c, 0xf6,
  0xc0, 0x4b, 0x55, 0xb4, 0xb3, 0x06, 0x76, 0x22, 0x06, 0xa0, 0x37, 0x4a,
  0xe2, 0x65, 0x33, 0x35, 0x07, 0xb5, 0xf4, 0xe6, 0x10, 0x9d, 0x97, 0x67,
  0xa6, 0x87, 0xab, 0xfd, 0x94, 0xc8, 0x12, 0xce, 0x43, 0x16, 0x89, 0xcd,
  0xb3, 0x5f, 0x6a, 0x8c, 0xb1, 0x62, 0xd6, 0x84, 0xd9, 0xc1, 0xe9, 0xc3,
  0xb2, 0xe1, 0xce, 0x8d, 0x8e, 0x1e, 0x09, 0xc1, 0x6b, 0x20, 0xbb, 0x99,
  0x82, 0x09, 0x1d, 0x80, 0x00, 0x9c, 0x0d, 0xad, 0xce, 0x66, 0xc4, 0x68,
  0xdc, 0xe1, 0xb9, 0x35, 0x47, 0x2d, 0x1e, 0x46, 0x32, 0x54, 0x67, 0x3b,
  0x92, 0xf8, 0x9d, 0x4e, 0xe1, 0x02, 0x81, 0x81, 0x00, 0xf8, 0xc7, 0x36,
  0x77, 0x42, 0x30, 0xb9, 0x01, 0xd3, 0xf2, 0x6c, 0xd2, 0x08, 0x98, 0xfe,
  0x1d, 0xa0, 0xe0, 0x99, 0xd1, 0xa6, 0xfe, 0xd1, 0x67, 0x24, 0x2f, 0x3d,
  0x74, 0xf4, 0x48, 0x1f, 0x32, 0xc5, 0xf1, 0xbc, 0xa3, 0x77, 0xbf, 0x4e,
  0x20, 0x0a, 0xcb, 0x37, 0x2c, 0xf8, 0xbb, 0x82, 0x10, 0xf5, 0x00, 0xa0,
  0x9e, 0xb1, 0x0b, 0xef, 0x4b, 0x85, 0x76, 0xc9, 0x4c, 0xa8, 0xe1, 0x7c,
  0x9d, 0xe9, 0xe0, 0x4f, 0xc9, 0xcc, 0x58, 0x85, 0x78, 0x9d, 0x13, 0x46,
  0x43, 0xe3, 0xb8, 0xf5, 0xf6, 0xda, 0x99, 0x60, 0x25, 0x61, 0x1a, 0x37,
  0x2f, 0x08, 0x9a, 0x39, 0x91, 0xf0, 0x21, 0x7c, 0x23, 0x6c, 0x8c, 0x9c,
  0xd0, 0x5f, 0x4d, 0x46, 0xaa, 0x30, 0xab, 0x97, 0x74, 0x81, 0x32, 0x09,
  0x34, 0x94, 0xc6, 0x3a, 0xfe, 0x16, 0x3e, 0xb1, 0x11, 0xc3, 0xc1, 0x3e,
  0x83, 0xb8, 0x55, 0x3d, 0x65, 0x02, 0x81, 0x81, 0x00, 0xe0, 0x87, 0x21,
  0xed, 0x58, 0xf0, 0x95, 0x88, 0x7f, 0x3c, 0x25, 0xf0, 0x41, 0xca, 0xca,
  0x2a, 0xaf, 0xe2, 0x4b, 0x94, 0x78, 0xd5, 0x41, 0xb1, 0x0d, 0x18, 0x68,
  0x35, 0x60, 0x29, 0x1c, 0x4b, 0x6f, 0xaf, 0xe8, 0xb6, 0x04, 0xfc, 0xa7,
  0x85, 0x9b, 0x11, 0xd0, 0x51, 0x57, 0x79, 0xd7, 0xbe, 0xd5, 0x4e, 0x67,
  0xc4, 0x5d, 0xde, 0x62, 0x20, 0xd3, 0xc4, 0x28, 0xcd, 0x94, 0x8f, 0xe6,
  0x34, 0x27, 0xf4, 0xdb, 0xfc, 0xcc, 0x4a, 0xc6, 0x9a, 0xbf, 0x48, 0x65,
  0x56, 0x6c, 0x08, 0x14, 0x88, 0x13, 0xa8, 0xbf, 0xd6, 0xb0, 0xd6, 0x20,
  0x90, 0xe6, 0xaa, 0xf4, 0x1f, 0x37, 0x1d, 0x13, 0xc8, 0x2d, 0x86, 0x83,
  0xda, 0x46, 0xa2, 0xdc, 0x93, 0x8a, 0xee, 0x85, 0x37, 0xdc, 0x8e, 0x16,
  0x86, 0xe3, 0x51, 0x3c, 0x87, 0x38, 0x6e, 0x72, 0xa5, 0xfe, 0x50, 0x42,
  0xcf, 0xc7, 0x82, 0xb0, 0xd9, 0x02, 0x81, 0x81, 0x00, 0xa1, 0x8b, 0xd3,
  0x3d, 0x7c, 0x18, 0xe1, 0x7a, 0x63, 0x64, 0x4f, 0xef, 0xcf, 0xaf, 0x71,
  0x8c, 0x51, 0xd4, 0xa7, 0x6d, 0xf1, 0xd0, 0x14, 0xb0, 0xb2, 0x59, 0x8e,
  0xc1, 0xec, 0x83, 0x0c, 0xe7, 0x4e, 0x8c, 0x9c, 0x5f, 0x56, 0x3a, 0x3f,
  0x04, 0x25, 0x9e, 0x32, 0x95, 0x1c, 0x6b, 0xbe, 0x99, 0x3e, 0x4f, 0x8a,
  0xfd, 0xa1, 0xa0, 0x4b, 0x62, 0xb2, 0x27, 0x21, 0xae, 0x8b, 0x17, 0xe9,
  0x71, 0x2d, 0xd7, 0x00, 0x58, 0xdd, 0x3e, 0x3a, 0x65, 0xc9, 0x32, 0x23,
  0xf5, 0x9f, 0xe1, 0x92, 0xaf, 0x1a, 0xe2, 0x70, 0x01, 0xb5, 0xdd, 0x6d,
  0x2a, 0x38, 0x9e, 0xd5, 0x75, 0x84, 0x06, 0x6a, 0x73, 0x22, 0x60, 0xe8,
  0xcf, 0x92, 0xa3, 0x3e, 0x98, 0xf3, 0x83, 0xe9, 0x94, 0xb8, 0xf4, 0x81,
  0xef, 0xc8, 0x10, 0x35, 0x6c, 0x9b, 0x8b, 0x58, 0x36, 0x5d, 0xf4, 0x95,
  0xa0, 0xb9, 0x49, 0x78, 0xd5, 0x02, 0x81, 0x81, 0x00, 0xc1, 0x5f, 0x40,
  0xb6, 0x04, 0xc2, 0x77, 0x56, 0xae, 0x96, 0x23, 0xea, 0x8f, 0x0f, 0x53,
  0x1c, 0x7e, 0x8c, 0x7c, 0x21, 0x6c, 0x0b, 0xe6, 0xde, 0xd0, 0x73, 0x73,
  0xd4, 0x7c, 0x74, 0x0b, 0x9d, 0x60, 0x9c, 0x74, 0xe4, 0xc6, 0xd8, 0xbe,
  0x82, 0x8f, 0xf2, 0x40, 0xa2, 0xbd, 0x9e, 0xff, 0x53, 0xa8, 0xac, 0x35,
  0x2c, 0x66, 0xd7, 0xcf, 0x55, 0x8c, 0x6c, 0xc5, 0xe3, 0x80, 0x8e, 0x8a,
  0x69, 0xe2, 0xfb, 0xbc, 0xb7, 0x35, 0x4f, 0x35, 0x4b, 0x33, 0x70, 0xeb,
  0x6e, 0x09, 0xee, 0xcf, 0x97, 0xfe, 0xae, 0x78, 0x42, 0x33, 0xdc, 0xc7,
  0x01, 0x64, 0xd8, 0x59, 0x15, 0xc5, 0x46, 0xb2, 0xb1, 0xd5, 0x9b, 0xa3,
  0x55, 0x4b, 0x3e, 0x9a, 0x90, 0x2b, 0xb8, 0x8f, 0x5d, 0x74, 0x03, 0x9f,
  0x9d, 0x1e, 0x8b, 0xe9, 0x80, 0x5f, 0xf6, 0xa7, 0xa1, 0x14, 0xad, 0x15,
  0x4d, 0x93, 0xfb, 0x97, 0xc9, 0x02, 0x81, 0x80, 0x20, 0xab, 0x75, 0xb3,
  0xf1, 0x7c, 0x47, 0x3e, 0x4b, 0x81, 0xb4, 0xf6, 0x3d, 0xb2, 0x5d, 0x7c,
  0x09, 0x3f, 0x33, 0x62, 0xa3, 0x14, 0xf1, 0xa8, 0x29, 0x64, 0x94, 0x6f,
  0xab, 0x98, 0xec, 0xeb, 0x65, 0x84, 0xa2, 0x34, 0xd0, 0xce, 0x14, 0x22,
  0xdd, 0xf5, 0x1c, 0x12, 0xd7, 0xb2, 0xb3, 0xb6, 0xa6, 0x84, 0xbc, 0x9d,
  0x1e, 0x32, 0x8e, 0x82, 0xb6, 0xe0, 0xfd, 0xe2, 0xa2, 0x01, 0xe1, 0x31,
  0x90, 0xac, 0xcf, 0xce, 0xcd, 0xf7, 0x55, 0x01, 0x38, 0x33, 0xa5, 0x1b,
  0x8f, 0x15, 0x44, 0x26, 0x26, 0xc2, 0x03, 0xae, 0xe8, 0xda, 0x57, 0x9d,
  0x3d, 0xfb, 0x7d, 0xb1, 0xe0, 0xa5, 0x0f, 0x74, 0xfd, 0x35, 0xd1, 0xa1,
  0xa4, 0xab, 0x0b, 0xf3, 0xa8, 0x6a, 0xeb, 0x66, 0x2f, 0x99, 0xab, 0xc1,
  0x43, 0x4f, 0x78, 0x69, 0x82, 0x99, 0xf4, 0xac, 0xb9, 0x28, 0x2d, 0xa3,
  0x1a, 0x56, 0x71, 0x65
};
static UINT test_device_cert_key_der_len = 1192;


#ifndef __LINUX__
ULONG test_stack_area[TOTAL_STACK_SPACE + 2000];
#endif


typedef struct
{
    VOID(*test_server)();
    VOID(*test_client)();

} TLS_HANDSHAKE_TEST_DATA;

static void tls_server_setup();
static void tls_client_setup();

static void test_split_record_tcp_server();
static void test_split_record_client();
static void test_split_record_server();
static void test_split_record_tcp_client();



static TLS_HANDSHAKE_TEST_DATA test_data[] =
{
    { test_split_record_tcp_server, test_split_record_client },

    //{ test_split_record_server, test_split_record_tcp_client },
};


static ULONG pool_area[2][NX_PACKET_POOL_SIZE];

/* Define the counters used in the demo application...  */
ULONG                   error_counter;


/* Define thread prototypes.  */

static void    sync_thread_entry(ULONG thread_input);
static void    ntest_0_entry(ULONG thread_input);
static void    ntest_1_entry(ULONG thread_input);
static void    ntest_0_connect_received(NX_TCP_SOCKET *server_socket, UINT port);
static void    ntest_0_disconnect_received(NX_TCP_SOCKET *server_socket);
extern void    _nx_ram_network_driver_1500(struct NX_IP_DRIVER_STRUCT *driver_req);

/* Define what the initial system looks like.  */
#ifndef __LINUX__
void    tx_application_define(void *first_unused_memory)
#else
#ifdef CTEST
void test_application_define(void *first_unused_memory);
void test_application_define(void *first_unused_memory)
#else
void           nx_secure_tls_packet_chain_test_application_define(void *first_unused_memory)
#endif
#endif
{
CHAR       *pointer;
UINT       status;

    /* Setup the working pointer.  */
#ifndef __LINUX__
    pointer = (CHAR*)test_stack_area;
#else
    pointer = (CHAR *) first_unused_memory;
#endif

    error_counter = 0;
    
    /* Create the main thread.  */
    tx_thread_create(&sync_thread, "thread sync", sync_thread_entry, 0,
                     sync_thread_stack, sizeof(sync_thread_stack),
                     3, 3, TX_NO_TIME_SLICE, TX_AUTO_START);

    /* Create the main thread.  */
    tx_thread_create(&ntest_0, "thread 0", ntest_0_entry, 0,  
                     server_stack, DEMO_STACK_SIZE, 
                     4, 4, TX_NO_TIME_SLICE, TX_DONT_START);

    pointer = pointer + DEMO_STACK_SIZE;

    /* Create the main thread.  */
    tx_thread_create(&ntest_1, "thread 1", ntest_1_entry, 0,  
                     client_stack, DEMO_STACK_SIZE, 
                     5, 5, TX_NO_TIME_SLICE, TX_DONT_START);

    pointer = pointer + DEMO_STACK_SIZE;

    /* Initialize the NetX system.  */
    nx_system_initialize();
      
    /* Create a packet pool.  */
    status = nx_packet_pool_create(&pool_0, "NetX Main Packet Pool", 1536, pool_area[0], sizeof(pool_area[0]));

    if(status)
    {
        printf("Error in function nx_packet_pool_create: 0x%x\n", status);
        error_counter++;
    }
      
    /* Create a packet pool.  */
    status = nx_packet_pool_create(&pool_1, "NetX Main Packet Pool", 600, pool_area[1], sizeof(pool_area[1]));

    if(status)
    {
        printf("Error in function nx_packet_pool_create: 0x%x\n", status);
        error_counter++;
    }

    /* Create an IP instance.  */
    status = nx_ip_create(&ip_0, "NetX IP Instance 0", IP_ADDRESS(1, 2, 3, 4), 0xFFFFFF00UL, &pool_0, _nx_ram_network_driver_1500,
                          pointer, IP_STACK_SIZE, 1);
    pointer = pointer + IP_STACK_SIZE;

    /* Create another IP instance.  */
    status += nx_ip_create(&ip_1, "NetX IP Instance 1", IP_ADDRESS(1, 2, 3, 5), 0xFFFFFF00UL, &pool_1, _nx_ram_network_driver_1500,
                           pointer, IP_STACK_SIZE, 1);
    pointer = pointer + IP_STACK_SIZE;

    if(status)
    {
        printf("Error in function nx_ip_create: 0x%x\n", status);
        error_counter++;
    }

    /* Enable ARP and supply ARP cache memory for IP Instance 0.  */
    status = nx_arp_enable(&ip_0, (void *) pointer, ARP_AREA_SIZE);
    pointer = pointer + ARP_AREA_SIZE;

    /* Enable ARP and supply ARP cache memory for IP Instance 1.  */
    status += nx_arp_enable(&ip_1, (void *) pointer, ARP_AREA_SIZE);
    pointer = pointer + ARP_AREA_SIZE;

    /* Check ARP enable status.  */
    if(status)
    {
        printf("Error in function nx_arp_enable: 0x%x\n", status);
        error_counter++;
    }

    /* Enable TCP processing for both IP instances.  */
    status = nx_tcp_enable(&ip_0);
    status += nx_tcp_enable(&ip_1);

    /* Check TCP enable status.  */
    if(status)
    {
        printf("Error in function tcp_enable: 0x%x\n", status);
        error_counter++;
    }
    
    nx_secure_tls_initialize();
}


/* Timestamp function - should return Unix time formatted 32-bit integer. */
static ULONG tls_timestamp_function(void)
{
    // Return a fixed epoch - 1500939067 seconds = 07/24/2017 @ 11:31pm (UTC) 
    // 1541030400 = 0x5BDA4200L = 11/01/2018 @ 12:00AM (UTC)
    return(0x5BDA4200L); 
}

/* Callback invoked whenever TLS has to validate a certificate from a remote host. Additional checking
   of the certificate may be done by the application here. */
static ULONG certificate_verification_callback(NX_SECURE_TLS_SESSION *session, NX_SECURE_X509_CERT* certificate)
{
const CHAR *dns_tld = "certificate_with_policies"; //"NX Secure Device Certificate";
UINT status;
NX_SECURE_X509_CERTIFICATE_STORE *store;
USHORT key_usage_bitfield;

    /* Check DNS entry string. */
    status = nx_secure_x509_common_name_dns_check(certificate, (UCHAR*)dns_tld, strlen(dns_tld));
  
    if(status != NX_SUCCESS)
    {
        printf("Error in certificate verification: DNS name did not match CN\n");
        return(status);
    }    
    
    /* Check CRL revocation status. */
    store = &session -> nx_secure_tls_credentials.nx_secure_tls_certificate_store;
    

    /* Check key usage extension. */
    status = nx_secure_x509_key_usage_extension_parse(certificate, &key_usage_bitfield);

    if(status != NX_SUCCESS)
    {
        printf("Error in parsing key usage extension: 0x%x\n", status);
        return(status);
    }

    if((key_usage_bitfield & NX_SECURE_X509_KEY_USAGE_DIGITAL_SIGNATURE) == 0 ||
       (key_usage_bitfield & NX_SECURE_X509_KEY_USAGE_NON_REPUDIATION)   == 0 ||
       (key_usage_bitfield & NX_SECURE_X509_KEY_USAGE_KEY_ENCIPHERMENT)  == 0)
    {
        printf("Expected key usage bitfield bits not set!\n");
        return(NX_SECURE_X509_KEY_USAGE_ERROR);
    }

    /* Extended key usage - look for specific OIDs. */
    status = nx_secure_x509_extended_key_usage_extension_parse(certificate, NX_SECURE_TLS_X509_TYPE_PKIX_KP_TIME_STAMPING);

    if(status != NX_SUCCESS)
    {
        printf("Expected certificate extension not found!\n");
    }

    return(NX_SUCCESS);
}


/* Define the test threads.  */

/* -----===== SERVER =====----- */

/* Define a TLS name to test the Server Name Indication extension. */
#define TLS_SNI_SERVER_NAME "testing"

static CHAR *html_data =  "HTTP/1.1 200 OK\r\n" \
        "Date: Fri, 15 Sep 2016 23:59:59 GMT\r\n" \
        "Content-Type: text/html\r\n" \
        "Content-Length: 200\r\n\r\n" \
        "<html>\r\n"\
        "<body>\r\n"\
        "<b>Hello NetX Secure User!</b>\r\n"\
        "This is a simple webpage\r\n"\
        "served up using NetX Secure!\r\n"\
        "</body>\r\n"\
        "</html>\r\n";

/* Callback for ClientHello extensions processing. */
static ULONG tls_server_callback(NX_SECURE_TLS_SESSION *tls_session, NX_SECURE_TLS_HELLO_EXTENSION *extensions, UINT num_extensions)
{
NX_SECURE_X509_DNS_NAME dns_name;
INT compare_value;
UINT status;
NX_SECURE_X509_CERT *cert_ptr;

    /* Process clienthello extensions. */
    status = _nx_secure_tls_session_sni_extension_parse(tls_session, extensions, num_extensions, &dns_name);

#ifdef NX_SECURE_TLS_SNI_EXTENSION_DISABLED
    if(status != NX_SECURE_TLS_EXTENSION_NOT_FOUND)
    {
        printf("SNI extension should not exist\n");
        error_counter++;
    }
#else
    if(status != NX_SUCCESS)
    {
        printf("SNI extension parsing failed with status 0x%x\n", status);
        error_counter++;
    }

    /* NULL-terminate name string. */
    dns_name.nx_secure_x509_dns_name[dns_name.nx_secure_x509_dns_name_length] = 0;

    /* Make sure our SNI name matches. */
    compare_value = memcmp(dns_name.nx_secure_x509_dns_name, TLS_SNI_SERVER_NAME, strlen(TLS_SNI_SERVER_NAME));

    if(compare_value || dns_name.nx_secure_x509_dns_name_length != strlen(TLS_SNI_SERVER_NAME))
    {
        printf("Error in SNI processing. SNI name '%s' does not match '%s'\n", dns_name.nx_secure_x509_dns_name, TLS_SNI_SERVER_NAME);
        error_counter++;
    }
#endif

    /* Find a certificate based on it's unique ID. */
    _nx_secure_tls_server_certificate_find(tls_session, &cert_ptr, 1);

    /* Set the certificate we want to use. */
    nx_secure_tls_active_certificate_set(tls_session, cert_ptr);

    return(NX_SUCCESS);
}

static TX_SEMAPHORE test_start_server;
static TX_SEMAPHORE test_end_server;
static TX_SEMAPHORE test_start_client;
static TX_SEMAPHORE test_end_client;

static void    sync_thread_entry(ULONG thread_input)
{

    /* Print out test information banner.  */
    printf("NetX Secure Test:   TLS Packet Chain Test..............................");

    /* Check for earlier error.  */
    if (error_counter)
    {
        printf("ERROR!\n");
        test_control_return(1);
    }


    tx_semaphore_create(&test_start_server, "test_start_server", 0);
    tx_semaphore_create(&test_end_server, "test_end_server", 0);
    tx_semaphore_create(&test_start_client, "test_start_client", 0);
    tx_semaphore_create(&test_end_client, "test_end_client", 0);

    tx_thread_resume(&ntest_0);
    tx_thread_resume(&ntest_1);


    while (1)
    {
        /* Start a test when both client and server thread completed the previous test. */
        tx_semaphore_put(&test_start_server);
        tx_semaphore_put(&test_start_client);

        tx_semaphore_get(&test_end_client, TX_WAIT_FOREVER);
        tx_semaphore_get(&test_end_server, TX_WAIT_FOREVER);
    }
}


static void    ntest_0_entry(ULONG thread_input)
{
UINT       status;
ULONG      actual_status;
UINT i;



    /* Ensure the IP instance has been initialized.  */
    status = nx_ip_status_check(&ip_0, NX_IP_INITIALIZE_DONE, &actual_status, NX_IP_PERIODIC_RATE);

    /* Check for error.  */
    if (status)
    {
        printf("Error in function nx_ip_status_check: 0x%x\n", status);
        error_counter++;
    }

    for (i = 0; i < sizeof(test_data) / sizeof(TLS_HANDSHAKE_TEST_DATA); i++)
    {
        tx_semaphore_get(&test_start_server, TX_WAIT_FOREVER);


        /* Create a socket.  */
        status = nx_tcp_socket_create(&ip_0, &server_socket, "Server Socket", 
                                      NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 16*1024,
                                      NX_NULL, ntest_0_disconnect_received);

        /* Check for error.  */
        if(status)
        {
            printf("Error in function nx_tcp_socket_create: 0x%x\n", status);
            error_counter++;
        }



        /* Setup this thread to listen.  */
        status = nx_tcp_server_socket_listen(&ip_0, 12, &server_socket, 5, ntest_0_connect_received);

        /* Check for error.  */
        if(status)
        {
            printf("Error in function nx_tcp_server_socket_listen: 0x%x\n", status);
            error_counter++;
        }


        /* Accept a client socket connection.  */
        status = nx_tcp_server_socket_accept(&server_socket, NX_IP_PERIODIC_RATE);


        /* Check for error.  */
        if(status)
        {
            printf("Error in function nx_tcp_server_socket_accept: 0x%x\n", status);
            error_counter++;
        }


        /* Call the actual test function. */
        test_data[i].test_server();

        if (error_counter)
        {
            printf("ERROR! Test %d\n", i + 1);
            test_control_return(1);
        }


        /* Disconnect the server socket.  */
        status = nx_tcp_socket_disconnect(&server_socket, NX_IP_PERIODIC_RATE); // NX_IP_PERIODIC_RATE * 10);

        /* Unaccept the server socket.  */
        status = nx_tcp_server_socket_unaccept(&server_socket);

        /* Check for error.  */
        if (status)
        {
            printf("Error in function nx_tcp_server_socket_unaccept: 0x%x\n", status);
            error_counter++;
        }

        /* Unlisten on the server port.  */
        status = nx_tcp_server_socket_unlisten(&ip_0, 12);

        /* Check for error.  */
        if (status)
        {
            printf("Error in function nx_tcp_server_socket_unlisten: 0x%x\n", status);
            error_counter++;
        }



        /* Delete the socket.  */
        status = nx_tcp_socket_delete(&server_socket);

        /* Check for error.  */
        if (status)
        {
            printf("Error in function nx_tcp_socket_delete: 0x%x\n", status);
            error_counter++;
        }

        tx_semaphore_put(&test_end_server);
    }

    tx_semaphore_get(&test_start_server, TX_WAIT_FOREVER);

    /* Determine if the test was successful.  */
    if (error_counter)
    {
        printf("ERROR!\n");
        test_control_return(1);
    }
    else
    {
        printf("SUCCESS!\n");
        test_control_return(0);
    }
}



/* -----===== CLIENT =====----- */

static ULONG tls_client_callback(NX_SECURE_TLS_SESSION *tls_session, NX_SECURE_TLS_HELLO_EXTENSION *extensions, UINT num_extensions)
{
    /* Process serverhello extensions. */
    return(NX_SUCCESS);
}


static void    ntest_1_entry(ULONG thread_input)
{
UINT         status;
UINT i;


    for (i = 0; i < sizeof(test_data) / sizeof(TLS_HANDSHAKE_TEST_DATA); i++)
    {
        tx_semaphore_get(&test_start_client, TX_WAIT_FOREVER);

        /* Create a socket.  */
        status = nx_tcp_socket_create(&ip_1, &client_socket, "Client Socket", 
                                      NX_IP_NORMAL, NX_FRAGMENT_OKAY, NX_IP_TIME_TO_LIVE, 1024*16,
                                      NX_NULL, NX_NULL);

        /* Check for error.  */
        if(status)
        {
            printf("Error in function nx_tcp_socket_create: 0x%x\n", status);
            error_counter++;
        }




        /* Bind the socket.  */
        status = nx_tcp_client_socket_bind(&client_socket, NX_ANY_PORT, NX_IP_PERIODIC_RATE);

        /* Check for error.  */
        if(status)
        {
            printf("Error in function nx_tcp_client_socket_bind: 0x%x\n", status);
            error_counter++;
        }

        status = nx_tcp_client_socket_connect(&client_socket, IP_ADDRESS(1, 2, 3, 4), 12, 5 * NX_IP_PERIODIC_RATE);

        if(status)
        {
            printf("Error in function nx_tcp_client_socket_connect: 0x%x\n", status);
            error_counter++;
        }

        /* Call the actual test function. */
        test_data[i].test_client();

        if (error_counter)
        {
            printf("ERROR! Test %d\n", i + 1);
            test_control_return(1);
        }

        /* Disconnect this socket.  */
        status = nx_tcp_socket_disconnect(&client_socket, NX_IP_PERIODIC_RATE); //NX_IP_PERIODIC_RATE * 10);

        /* Bind the socket.  */
        status = nx_tcp_client_socket_unbind(&client_socket);

        /* Check for error.  */
        if(status)
        {
            printf("Error in TLS Client function nx_tcp_client_socket_unbind: 0x%x\n", status);
            error_counter++;
        }




        /* Delete the socket.  */
        status = nx_tcp_socket_delete(&client_socket);

        /* Check for error.  */
        if(status)
        {
            printf("Error in TLS Client function nx_tcp_socket_delete: %x\n", status);
            error_counter++;
        }

        tx_semaphore_put(&test_end_client);
    }

    tx_semaphore_get(&test_start_client, TX_WAIT_FOREVER);
}

static void    ntest_0_connect_received(NX_TCP_SOCKET *socket_ptr, UINT port)
{

    /* Check for the proper socket and port.  */
    if((socket_ptr != &server_socket) || (port != 12))
        error_counter++;
}

static void    ntest_0_disconnect_received(NX_TCP_SOCKET *socket)
{

    /* Check for proper disconnected socket.  */
    if(socket != &server_socket)
        error_counter++;
}

static void tls_server_setup()
{
UINT status;

    /* Create a TLS session for our socket.  */
    status =  nx_secure_tls_session_create(&server_tls_session,
                                           &nx_crypto_tls_ciphers,
                                           server_crypto_metadata,
                                           sizeof(server_crypto_metadata));

    /* Check for error.  */
    if(status)
    {
        printf("Error in function nx_secure_tls_session_create: 0x%x\n", status);
        error_counter++;
    }

    /* Setup our packet reassembly buffer. */
    nx_secure_tls_session_packet_buffer_set(&server_tls_session, server_packet_buffer, sizeof(server_packet_buffer));

    /* Enable Client Certificate Verification. */
    nx_secure_tls_session_client_verify_enable(&server_tls_session);

    /* Add a timestamp function for time checking and timestamps in the TLS handshake. */
    _nx_secure_tls_session_time_function_set(&server_tls_session, tls_timestamp_function);

    /* Setup the callback invoked when TLS has a certificate it wants to verify so we can
       do additional checks not done automatically by TLS. */
    _nx_secure_tls_session_certificate_callback_set(&server_tls_session, certificate_verification_callback);
    
    /* Set callback for server TLS extension handling. */
    _nx_secure_tls_session_server_callback_set(&server_tls_session, tls_server_callback);



    /////////////////////////////////////////////////////////////////////////////////////////////////////////
    // Initialize our certificate
    nx_secure_x509_certificate_initialize(&certificate, test_device_cert_der, test_device_cert_der_len, NX_NULL, 0, test_device_cert_key_der, test_device_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER);
    nx_secure_tls_server_certificate_add(&server_tls_session, &certificate, 1);

    nx_secure_x509_certificate_initialize(&server_certificate, test_server_cert_der, test_server_cert_der_len, NX_NULL, 0, test_server_cert_key_der, test_server_cert_key_der_len, NX_SECURE_X509_KEY_TYPE_RSA_PKCS1_DER);
    nx_secure_tls_server_certificate_add(&server_tls_session, &server_certificate, 2);

    nx_secure_x509_certificate_initialize(&ica_certificate, ica_cert_der, ica_cert_der_len, NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE);
    nx_secure_tls_local_certificate_add(&server_tls_session, &ica_certificate);

    // If we are testing client certificate verify, allocate remote certificate space.
    nx_secure_tls_remote_certificate_allocate(&server_tls_session, &client_remote_certificate, client_remote_cert_buffer, sizeof(client_remote_cert_buffer));
    nx_secure_tls_remote_certificate_allocate(&server_tls_session, &client_remote_issuer, client_remote_issuer_buffer, sizeof(client_remote_issuer_buffer));

    /* Add a CA Certificate to our trusted store for verifying incoming client certificates. */
    nx_secure_x509_certificate_initialize(&trusted_certificate, ca_cert_der, ca_cert_der_len, NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE);
    nx_secure_tls_trusted_certificate_add(&server_tls_session, &trusted_certificate);

    /////////////////////////////////////////////////////////////////////////////////////////////////////////

}
static NX_SECURE_X509_DNS_NAME dns_name;
static void tls_client_setup()
{
UINT status;


    /* Create a TLS session for our socket.  */
    status = nx_secure_tls_session_create(&client_tls_session,
                                          &nx_crypto_tls_ciphers,
                                          client_crypto_metadata,
                                          sizeof(client_crypto_metadata));

    /* Check for error.  */
    if (status)
    {
        printf("Error in function nx_secure_tls_session_create: 0x%x\n", status);
        error_counter++;
    }


    /* Setup our packet reassembly buffer. */
    nx_secure_tls_session_packet_buffer_set(&client_tls_session, client_packet_buffer, sizeof(client_packet_buffer));

    /* Make sure client certificate verification is disabled. */
    nx_secure_tls_session_client_verify_disable(&client_tls_session);

    /* Need to allocate space for the certificate coming in from the remote host. */
    nx_secure_tls_remote_certificate_allocate(&client_tls_session, &remote_certificate, remote_cert_buffer, sizeof(remote_cert_buffer));
    nx_secure_tls_remote_certificate_allocate(&client_tls_session, &remote_issuer, remote_issuer_buffer, sizeof(remote_issuer_buffer));
    nx_secure_tls_remote_certificate_allocate(&client_tls_session, &remote_issuer2, remote_issuer2_buffer, sizeof(remote_issuer2_buffer));

    /* Add a CA Certificate to our trusted store for verifying incoming server certificates. */
    nx_secure_x509_certificate_initialize(&trusted_certificate, ca_cert_der, ca_cert_der_len, NX_NULL, 0, NULL, 0, NX_SECURE_X509_KEY_TYPE_NONE);
    nx_secure_tls_trusted_certificate_add(&client_tls_session, &trusted_certificate);


    /* Add a timestamp function for time checking and timestamps in the TLS handshake. */
    _nx_secure_tls_session_time_function_set(&client_tls_session, tls_timestamp_function);

    /* Setup the callback invoked when TLS has a certificate it wants to verify so we can
    do additional checks not done automatically by TLS. */
    _nx_secure_tls_session_certificate_callback_set(&client_tls_session, certificate_verification_callback);

    /* Set callback for server TLS extension handling. */
    _nx_secure_tls_session_client_callback_set(&client_tls_session, tls_client_callback);


    /* Set up a DNS name for the Server Name Indication extension. The server thread will compare
    * to make sure the name was sent and recieved appropriately. */
    nx_secure_x509_dns_name_initialize(&dns_name, TLS_SNI_SERVER_NAME, (USHORT)strlen(TLS_SNI_SERVER_NAME));
    nx_secure_tls_session_sni_extension_set(&client_tls_session, &dns_name);

}


static UCHAR client_key_exchange[384];
static UCHAR server_hello_cert_done[] =
{
    0x16, 0x03, 0x03, 0x08, 0x39,

    /* Server Hello */
    0x02, 0x00, 0x00, 0x2d, 0x03, 0x03, 0x5b, 0xda, 0x42, 0x00, 0xbe, 0x18, 0x00, 0x00, 0x84, 0x67,
    0x00, 0x00, 0xe1, 0x4a, 0x00, 0x00, 0x6c, 0x3d, 0x00, 0x00, 0xd6, 0x2c, 0x00, 0x00, 0xae, 0x72,
    0x00, 0x00, 0x52, 0x69, 0x00, 0x00, 0x00, 0x00, 0x3d, 0x00, 0x00, 0x05, 0xff, 0x01, 0x00, 0x01,
    0x00,

    /* Certificate */
    0x0b, 0x00, 0x08, 0x04, 0x00, 0x08, 0x01, 0x00, 0x04, 0x18, 0x30, 0x82, 0x04, 0x14, 0x30, 0x82,
    0x02, 0xfc, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x02, 0x10, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a,
    0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30, 0x6f, 0x31, 0x0b, 0x30, 0x09,
    0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
    0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c,
    0x0d, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x31, 0x12,
    0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x09, 0x4e, 0x58, 0x20, 0x53, 0x65, 0x63, 0x75,
    0x72, 0x65, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x1e, 0x4e, 0x58, 0x20,
    0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x49, 0x6e, 0x74, 0x65,
    0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x43, 0x41, 0x30, 0x1e, 0x17, 0x0d, 0x31,
    0x37, 0x31, 0x31, 0x33, 0x30, 0x30, 0x30, 0x31, 0x36, 0x34, 0x30, 0x5a, 0x17, 0x0d, 0x32, 0x37,
    0x31, 0x31, 0x32, 0x38, 0x30, 0x30, 0x31, 0x36, 0x34, 0x30, 0x5a, 0x30, 0x74, 0x31, 0x0b, 0x30,
    0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03,
    0x55, 0x04, 0x08, 0x0c, 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31,
    0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0d, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73,
    0x73, 0x20, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b,
    0x0c, 0x0b, 0x4e, 0x65, 0x74, 0x58, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x31, 0x22, 0x30,
    0x20, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x19, 0x63, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63,
    0x61, 0x74, 0x65, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x5f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x69, 0x65,
    0x73, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
    0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01,
    0x01, 0x00, 0xda, 0x31, 0xa1, 0xae, 0x67, 0xaf, 0x9c, 0x50, 0x5f, 0x1b, 0xd4, 0xce, 0x6d, 0x3c,
    0x3c, 0xa6, 0xd2, 0x41, 0x86, 0x7a, 0xed, 0x81, 0x65, 0x82, 0x3f, 0xa1, 0x54, 0x89, 0xba, 0x4d,
    0x7a, 0x9e, 0xab, 0x99, 0x24, 0x23, 0x19, 0xf8, 0xb4, 0x83, 0xe1, 0xb0, 0x08, 0x7b, 0x6f, 0x02,
    0x7d, 0x80, 0x2e, 0xd9, 0xb5, 0xe1, 0xb2, 0x13, 0x3b, 0x23, 0x32, 0xc8, 0x0b, 0xad, 0xc4, 0xac,
    0x95, 0xa6, 0x82, 0x0e, 0xec, 0x62, 0xfa, 0x7f, 0xf5, 0x2c, 0xc7, 0xe6, 0x4e, 0x28, 0x30, 0xb6,
    0x66, 0x5d, 0xa8, 0x28, 0xeb, 0xbe, 0xfd, 0xd3, 0xa7, 0xc5, 0xcc, 0x13, 0x3b, 0x50, 0xff, 0x48,
    0x2f, 0x81, 0xb8, 0x8d, 0x32, 0x97, 0x71, 0xab, 0xd0, 0x1b, 0xe4, 0xb5, 0x80, 0x87, 0x16, 0xdb,
    0x50, 0x35, 0xef, 0x5d, 0x46, 0x32, 0xdd, 0x29, 0x79, 0xb9, 0x8f, 0xdc, 0xcb, 0x6a, 0x50, 0x46,
    0xa2, 0x20, 0xd8, 0xc3, 0x44, 0x8a, 0xd7, 0x5d, 0xc2, 0xe3, 0x0d, 0xc3, 0x33, 0xd3, 0x23, 0xc7,
    0x11, 0x21, 0xde, 0x34, 0xac, 0xb0, 0x9b, 0x4e, 0xdc, 0x4c, 0x5e, 0xf8, 0x1d, 0xef, 0x0f, 0x28,
    0x79, 0x33, 0xf6, 0x8a, 0xfe, 0x6e, 0xb9, 0xd5, 0x49, 0xf0, 0x1f, 0x57, 0xca, 0x92, 0xa6, 0x93,
    0x57, 0x51, 0x5c, 0xf8, 0x54, 0x9b, 0xf0, 0x46, 0x3a, 0x10, 0xf5, 0x6f, 0x85, 0xb7, 0x36, 0x5a,
    0xfd, 0xda, 0x17, 0x2c, 0xb4, 0x22, 0x82, 0xe1, 0xd6, 0xf1, 0x06, 0x2b, 0x22, 0x94, 0x72, 0xd2,
    0xcc, 0x84, 0x6f, 0x53, 0x41, 0xfb, 0xc9, 0x5f, 0xc8, 0x1e, 0x16, 0x57, 0x29, 0x40, 0x73, 0x3b,
    0xc8, 0xae, 0x06, 0x3e, 0x7b, 0xa7, 0x2a, 0x41, 0x8d, 0x96, 0xc3, 0xfd, 0xa2, 0x31, 0x64, 0x60,
    0xf1, 0x1d, 0x0a, 0xa3, 0x3b, 0xb3, 0x42, 0x2c, 0x2a, 0x0c, 0x59, 0x47, 0x19, 0x0f, 0x8a, 0xc0,
    0x7a, 0x9d, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x81, 0xb4, 0x30, 0x81, 0xb1, 0x30, 0x09, 0x06,
    0x03, 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x11, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
    0x86, 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x06, 0x40, 0x30, 0x0b, 0x06, 0x03, 0x55,
    0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x05, 0xe0, 0x30, 0x2c, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
    0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x1f, 0x16, 0x1d, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53, 0x4c,
    0x20, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69,
    0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04,
    0x14, 0x98, 0x0c, 0xd6, 0x1c, 0x08, 0x75, 0x6d, 0x49, 0x3f, 0xa4, 0xe9, 0x2d, 0xf9, 0xd1, 0x70,
    0x1a, 0xd7, 0xef, 0xc6, 0x05, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16,
    0x80, 0x14, 0x8e, 0x6a, 0xb0, 0xfe, 0x49, 0xc5, 0x6a, 0x96, 0x9e, 0xba, 0xb8, 0xb6, 0x58, 0xfc,
    0x52, 0x7f, 0xab, 0x51, 0xf2, 0x3a, 0x30, 0x16, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x01, 0x01, 0xff,
    0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x08, 0x30, 0x0d,
    0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01,
    0x01, 0x00, 0x71, 0x9f, 0xcd, 0x22, 0x0c, 0xc1, 0x2d, 0x31, 0xfb, 0x30, 0x29, 0x67, 0x66, 0xd6,
    0x1f, 0xbd, 0x4c, 0x37, 0xdc, 0xca, 0x0f, 0xf9, 0x59, 0xe8, 0xb7, 0xaf, 0xcc, 0x2a, 0x95, 0x13,
    0xc4, 0x47, 0x70, 0x6e, 0xde, 0xf0, 0xbb, 0x2f, 0x58, 0x1f, 0xab, 0xe5, 0x53, 0x78, 0xa5, 0xe4,
    0xaf, 0x65, 0xb6, 0xad, 0x99, 0x4d, 0xa1, 0x5a, 0x11, 0x21, 0x19, 0x29, 0x4a, 0xb9, 0x7e, 0x7f,
    0xce, 0xb6, 0x63, 0x0c, 0x57, 0x3c, 0x04, 0x62, 0x07, 0x8c, 0x3a, 0x84, 0x60, 0x6d, 0x36, 0x6a,
    0xeb, 0xd3, 0xbe, 0x06, 0x78, 0xd0, 0x2c, 0x2b, 0xa8, 0xef, 0x06, 0x5c, 0xd5, 0x76, 0x0a, 0x15,
    0x88, 0x36, 0x77, 0x34, 0x8f, 0x40, 0x81, 0xad, 0xfd, 0xa2, 0x34, 0x6d, 0xf0, 0xd7, 0xe9, 0x12,
    0x49, 0x62, 0x1a, 0x38, 0x4f, 0x9a, 0xbd, 0x2d, 0x3c, 0x7a, 0xec, 0x2a, 0x53, 0xbf, 0x9b, 0x6f,
    0x6f, 0x58, 0x30, 0xcf, 0x09, 0xa6, 0x3c, 0x84, 0xe4, 0xe2, 0x27, 0x25, 0x58, 0x9e, 0xab, 0x43,
    0x88, 0x9c, 0xc7, 0xe2, 0xac, 0xff, 0xd5, 0x73, 0x7a, 0xf9, 0xf3, 0x5d, 0x09, 0x40, 0xcc, 0x6b,
    0x9e, 0x97, 0x35, 0x83, 0x1d, 0xb8, 0x0e, 0xd6, 0x1a, 0xbb, 0xa1, 0x9d, 0x7f, 0x54, 0x77, 0x72,
    0x66, 0x0f, 0x62, 0x94, 0xbb, 0x9e, 0xf6, 0x2e, 0xb1, 0x68, 0x5f, 0xb4, 0x73, 0x85, 0x92, 0x3d,
    0x97, 0xd3, 0xd1, 0x1a, 0x5d, 0x56, 0xb4, 0x0e, 0x92, 0x99, 0x61, 0x5f, 0x56, 0xf3, 0xf4, 0xc4,
    0xec, 0xfa, 0xde, 0x71, 0xee, 0x47, 0xaf, 0xb5, 0x36, 0x6d, 0x01, 0xcf, 0xc8, 0xc6, 0x93, 0x65,
    0x7a, 0x1e, 0x1f, 0x1b, 0x1f, 0xf2, 0xf7, 0x0e, 0xd9, 0x21, 0x61, 0xf3, 0x39, 0xf3, 0xa9, 0x1c,
    0x8a, 0x3d, 0x90, 0x0c, 0x49, 0x85, 0x69, 0x08, 0xc1, 0x3e, 0x1d, 0xbb, 0x63, 0xa6, 0xd8, 0x57,
    0xe6, 0x00, 0x00, 0x03, 0xe3, 0x30, 0x82, 0x03, 0xdf, 0x30, 0x82, 0x02, 0xc7, 0xa0, 0x03, 0x02,
    0x01, 0x02, 0x02, 0x01, 0x02, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
    0x01, 0x0b, 0x05, 0x00, 0x30, 0x7a, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
    0x02, 0x55, 0x53, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41,
    0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x53, 0x61, 0x6e, 0x20, 0x44,
    0x69, 0x65, 0x67, 0x6f, 0x31, 0x16, 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0d, 0x45,
    0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x4c, 0x6f, 0x67, 0x69, 0x63, 0x31, 0x14, 0x30, 0x12,
    0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x0b, 0x4e, 0x65, 0x74, 0x58, 0x20, 0x53, 0x65, 0x63, 0x75,
    0x72, 0x65, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, 0x4e, 0x65, 0x74,
    0x58, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x41,
    0x30, 0x1e, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x33, 0x33, 0x31, 0x32, 0x31, 0x30, 0x30, 0x30, 0x32,
    0x5a, 0x17, 0x0d, 0x32, 0x37, 0x30, 0x33, 0x32, 0x39, 0x32, 0x31, 0x30, 0x30, 0x30, 0x32, 0x5a,
    0x30, 0x6f, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x55, 0x53, 0x31,
    0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, 0x0c, 0x02, 0x43, 0x41, 0x31, 0x16, 0x30, 0x14,
    0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0d, 0x45, 0x78, 0x70, 0x72, 0x65, 0x73, 0x73, 0x20, 0x4c,
    0x6f, 0x67, 0x69, 0x63, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x09, 0x4e,
    0x58, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x31, 0x27, 0x30, 0x25, 0x06, 0x03, 0x55, 0x04,
    0x03, 0x0c, 0x1e, 0x4e, 0x58, 0x20, 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x54, 0x65, 0x73,
    0x74, 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74, 0x65, 0x20, 0x43,
    0x41, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
    0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01,
    0x01, 0x00, 0xa7, 0xa4, 0xd9, 0xd0, 0x19, 0x84, 0x4e, 0xab, 0x8e, 0x08, 0xad, 0x30, 0xe6, 0x79,
    0x46, 0x46, 0xe2, 0xd3, 0x13, 0xc1, 0x69, 0xa9, 0x4a, 0xc9, 0xc8, 0x95, 0x54, 0xa8, 0x76, 0x41,
    0x63, 0x10, 0xc4, 0xe4, 0xfd, 0x08, 0x69, 0x7f, 0x89, 0x79, 0x82, 0x62, 0xd7, 0x90, 0x73, 0x55,
    0x06, 0x0d, 0x62, 0xec, 0x1b, 0x2d, 0xaf, 0xf2, 0x39, 0x14, 0x47, 0x5b, 0x9d, 0x7a, 0xd2, 0xe3,
    0xf9, 0xae, 0x37, 0x49, 0xd0, 0xb8, 0x01, 0xf2, 0x1a, 0x84, 0x9a, 0x50, 0x37, 0x4d, 0xd6, 0xed,
    0x7c, 0x44, 0xef, 0xd1, 0xb8, 0x05, 0x4b, 0x3c, 0x05, 0x59, 0x4a, 0xcd, 0xc1, 0xce, 0x6d, 0xb9,
    0xbe, 0xb0, 0xc4, 0xe5, 0x44, 0x02, 0xfd, 0xfa, 0x61, 0x3e, 0x59, 0x3e, 0x4b, 0x0f, 0xe6, 0x20,
    0xda, 0xf1, 0xca, 0xb5, 0x67, 0x52, 0x2b, 0x2e, 0x1b, 0xfc, 0xf1, 0xc6, 0x55, 0x88, 0xf9, 0x28,
    0xaa, 0xd9, 0x55, 0x6a, 0xc7, 0x61, 0x94, 0x24, 0x8d, 0x63, 0xfb, 0xa6, 0x8a, 0x06, 0x21, 0xe2,
    0x8e, 0xf7, 0xa8, 0x0b, 0x91, 0x39, 0xff, 0x8d, 0xde, 0xb8, 0x0b, 0x16, 0x8a, 0xc6, 0xac, 0xe0,
    0x61, 0x69, 0x98, 0x4a, 0x90, 0xfd, 0x03, 0xe3, 0x38, 0x90, 0xc7, 0xe3, 0x13, 0x40, 0x12, 0xc5,
    0x44, 0x07, 0x44, 0x57, 0x43, 0xbb, 0xa4, 0x67, 0x72, 0x20, 0xbb, 0x97, 0xe6, 0xa1, 0x32, 0xb2,
    0x73, 0xf2, 0x8d, 0xe3, 0x23, 0xdc, 0x06, 0xc0, 0x1f, 0xfc, 0xe3, 0x3a, 0xcc, 0x9c, 0xf8, 0x00,
    0x87, 0x39, 0x0d, 0x1e, 0x4d, 0x59, 0x15, 0x16, 0xe6, 0x63, 0x5b, 0x53, 0x6d, 0x79, 0x2f, 0xb7,
    0x5a, 0xcc, 0x37, 0xc9, 0x96, 0xff, 0x46, 0xac, 0xdd, 0x44, 0x9f, 0x3a, 0xc8, 0x83, 0xeb, 0x1b,
    0x67, 0xa0, 0x2d, 0xa8, 0x34, 0x19, 0xf0, 0x5b, 0xe8, 0x59, 0xf7, 0xc9, 0x08, 0xab, 0x09, 0x71,
    0x78, 0x75, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x7b, 0x30, 0x79, 0x30, 0x09, 0x06, 0x03, 0x55,
    0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x2c, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
    0x42, 0x01, 0x0d, 0x04, 0x1f, 0x16, 0x1d, 0x4f, 0x70, 0x65, 0x6e, 0x53, 0x53, 0x4c, 0x20, 0x47,
    0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x64, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
    0x63, 0x61, 0x74, 0x65, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x8e,
    0x6a, 0xb0, 0xfe, 0x49, 0xc5, 0x6a, 0x96, 0x9e, 0xba, 0xb8, 0xb6, 0x58, 0xfc, 0x52, 0x7f, 0xab,
    0x51, 0xf2, 0x3a, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
    0x1b, 0x8d, 0x06, 0xd9, 0x6b, 0xad, 0xee, 0x82, 0x24, 0x26, 0x55, 0x9a, 0x1b, 0x03, 0x44, 0x92,
    0x0a, 0x06, 0x92, 0x48, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
    0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x18, 0x5a, 0x50, 0xb6, 0x44, 0xba, 0x68, 0xac,
    0x7f, 0x06, 0x0f, 0xbc, 0x1a, 0x58, 0x59, 0xf1, 0xf1, 0xe3, 0xb8, 0x0d, 0x74, 0xdd, 0x74, 0x26,
    0x6a, 0xea, 0xfc, 0xfe, 0x06, 0x53, 0xe9, 0x80, 0xe3, 0x07, 0x83, 0x8a, 0xc9, 0xc9, 0xc0, 0x93,
    0xb4, 0xc2, 0x59, 0x71, 0xa7, 0x58, 0xac, 0x32, 0x0f, 0x32, 0x9c, 0x5b, 0x4d, 0x53, 0xcb, 0xdc,
    0x04, 0x00, 0x04, 0x27, 0x37, 0x2d, 0x11, 0x5b, 0xaa, 0xf6, 0x45, 0x8a, 0xc4, 0x74, 0x2e, 0x47,
    0x83, 0xb8, 0x5e, 0x3a, 0xc0, 0x10, 0xaf, 0xc1, 0xd2, 0x61, 0x1c, 0x85, 0x31, 0x16, 0x74, 0x05,
    0xf4, 0xc6, 0xd8, 0x35, 0x83, 0x13, 0xca, 0x25, 0x5b, 0x22, 0xc6, 0x2c, 0x32, 0x8d, 0x3a, 0x3f,
    0x78, 0x79, 0x57, 0xbe, 0x97, 0x96, 0x90, 0x20, 0x7d, 0xe5, 0xe6, 0xe6, 0x42, 0xde, 0xd3, 0xd4,
    0xb4, 0x18, 0x34, 0x9d, 0xc3, 0x95, 0x2d, 0xb2, 0x91, 0x1d, 0xfe, 0x3c, 0xee, 0x5c, 0xda, 0xdd,
    0xd7, 0xf5, 0x05, 0xf1, 0xbd, 0xa0, 0x2f, 0x0a, 0x03, 0x2e, 0x45, 0x26, 0x9c, 0xac, 0x16, 0x59,
    0x9a, 0x7f, 0xf2, 0x3a, 0x3e, 0xdb, 0x4b, 0x63, 0x58, 0x38, 0x0b, 0x64, 0x5e, 0x24, 0x15, 0x92,
    0xb5, 0xcf, 0x33, 0xe9, 0x61, 0x1f, 0xb9, 0x33, 0xa1, 0x09, 0x41, 0x9f, 0x05, 0x11, 0xad, 0x07,
    0x0b, 0x60, 0x67, 0x1a, 0x4c, 0x6c, 0x93, 0x36, 0x90, 0x20, 0xac, 0xb3, 0x99, 0x61, 0xa0, 0xda,
    0xe5, 0x8d, 0x3f, 0x66, 0xd1, 0xf3, 0x91, 0x40, 0x60, 0xcf, 0x97, 0xbb, 0x15, 0xb1, 0x81, 0x4e,
    0xbf, 0xba, 0xef, 0x20, 0x36, 0x6f, 0x00, 0x40, 0xa2, 0xa3, 0x24, 0x5c, 0x61, 0xd5, 0xa5, 0x64,
    0xbf, 0xbe, 0x29, 0xdf, 0x47, 0x4b, 0xc8, 0x76, 0x4f, 0x2e, 0x4c, 0x5c, 0xed, 0x99, 0x26, 0xe8,
    0xf1, 0x72, 0x5e, 0x9b, 0x86, 0x73, 0xda, 0xfb,

    0x16, 0x03, 0x03, 0x00, 0x04,
    /* Server Hello Done */
    0x0e, 0x00, 0x00, 0x00
};

/* Test of a server sending one record by calling multiple nx_tcp_socket_send. */
static void test_split_record_tcp_server()
{
    NX_PACKET *send_packet;
    NX_PACKET *receive_packet;
    ULONG      bytes_copied;
    UINT       status;

    /* Receive ClientHello. */
    status = nx_tcp_socket_receive(&server_socket, &receive_packet, NX_WAIT_FOREVER);
    EXPECT_EQ(NX_SUCCESS, status);

    /* Release the ClientHello packet. */
    nx_packet_release(receive_packet);

    status = nx_packet_allocate(&pool_0, &send_packet, NX_IPv4_TCP_PACKET, NX_WAIT_FOREVER);
    EXPECT_EQ(NX_SUCCESS, status);

    status = nx_packet_data_append(send_packet, server_hello_cert_done, sizeof(server_hello_cert_done) - 8, &pool_0, NX_WAIT_FOREVER);
    EXPECT_EQ(NX_SUCCESS, status);

    status = nx_tcp_socket_send(&server_socket, send_packet, NX_WAIT_FOREVER);
    EXPECT_EQ(NX_SUCCESS, status);

    tx_thread_sleep(100);

    status = nx_packet_allocate(&pool_0, &send_packet, NX_IPv4_TCP_PACKET, NX_WAIT_FOREVER);
    EXPECT_EQ(NX_SUCCESS, status);

    status = nx_packet_data_append(send_packet, &server_hello_cert_done[sizeof(server_hello_cert_done) - 8], 8, &pool_0, NX_WAIT_FOREVER);
    EXPECT_EQ(NX_SUCCESS, status);

    status = nx_tcp_socket_send(&server_socket, send_packet, NX_WAIT_FOREVER);
    EXPECT_EQ(NX_SUCCESS, status);

    /* Receive ClientKeyExchange. */
    status = nx_tcp_socket_receive(&server_socket, &receive_packet, NX_WAIT_FOREVER);
    EXPECT_EQ(NX_SUCCESS, status);

    nx_packet_data_extract_offset(receive_packet, 0, client_key_exchange, sizeof(client_key_exchange), &bytes_copied);
    EXPECT_EQ(NX_SUCCESS, status);

    EXPECT_TRUE(bytes_copied >= 9);

    /* Content Type: Handshake (22). */
    EXPECT_EQ(22, client_key_exchange[0]);

    /* Length > 0 */
    EXPECT_TRUE(client_key_exchange[3] > 0 || client_key_exchange[4] > 0);

    /* Handshake Protocol: Client Key Exchange. */
    EXPECT_EQ(16, client_key_exchange[5]);

    /* Release the ClientHello packet. */
    nx_packet_release(receive_packet);

}

static void test_split_record_client()
{
    UINT status;

    tls_client_setup();

    status = nx_secure_tls_session_start(&client_tls_session, &client_socket, NX_WAIT_FOREVER);

    /* End the TLS session. This is required to properly shut down the TLS connection. */
    status = nx_secure_tls_session_end(&client_tls_session, NX_WAIT_FOREVER);

    /* If the session did not shut down cleanly, this is a possible security issue. */
    if (status)
    {
        printf("Error in TLS Client session end: %x\n", status);
        error_counter++;
    }

    /* Delete TLS session. */
    status = nx_secure_tls_session_delete(&client_tls_session);

    /* Check for error.  */
    if (status)
    {
        printf("Error in TLS Client function nx_secure_tls_session_delete: %x\n", status);
        error_counter++;
    }

}


#else
#ifdef CTEST
void test_application_define(void *first_unused_memory);
void test_application_define(void *first_unused_memory)
#else
VOID    nx_secure_tls_packet_chain_test_application_define(void *first_unused_memory)
#endif
{

    /* Print out test information banner.  */
    printf("NetX Secure Test:   TLS Packet Chain Test..............................N/A\n");
    test_control_return(3);
}
#endif
